Skip to content

terry-writer/auth-server

Repository files navigation

auth-server

Go で認証・認可基盤をゼロから実装した学習・ポートフォリオ用プロジェクトです。

JWT の署名検証、リフレッシュトークンのローテーション、OAuth 2.0 / Google ログインを、ライブラリに隠蔽せず自前で実装することで、Cognito や Auth0 が内部で何をしているかを理解することを目的としています。


概要

項目 内容
言語 Go 1.21
認証方式 JWT(RS256、手実装)+ OAuth 2.0(Google)
トークン管理 アクセストークン(1時間)+ リフレッシュトークン(7日、ローテーション)
パスワード bcrypt(DefaultCost)
ストレージ インメモリ(sync.Mutex による並行安全)

ファイル構成

auth-server/
├── main.go       # サーバー起動・ルーティング
├── auth.go       # JWT 生成・検証(RS256 手実装)
├── handler.go    # 各エンドポイントのハンドラ
├── store.go      # ユーザー・トークンのインメモリストア
├── password.go   # bcrypt ラッパー
├── oauth.go      # Google OAuth 2.0 / コールバック処理
├── .env.example  # 環境変数のテンプレート
└── .gitignore

エンドポイント

メソッド パス 説明
POST /register メール・パスワードでユーザー登録
POST /login ログイン → アクセストークン+リフレッシュトークン発行
GET /me Bearer トークンを検証してユーザー情報を返す
POST /refresh リフレッシュトークンを使って新しいトークンペアを発行
GET /auth/google Google ログイン開始(OAuth 2.0)
GET /callback Google からのコールバック処理

設計判断

なぜ JWT を手実装したのか

golang-jwt/jwt などのライブラリを使えば数行で実装できます。あえて使わなかったのは、署名・検証の内部構造(Base64URL エンコード、PKCS1v15 署名、有効期限検証)を自分の手で確かめるためです。

ライブラリは正しく使うために、中で何が起きているかを知っておく必要があります。

なぜ RS256(非対称暗号)を選んだのか

HS256(共通鍵)は実装がシンプルですが、検証する側にも秘密鍵を渡す必要があります。RS256 は秘密鍵で署名し、公開鍵で検証するため、マイクロサービス構成で「発行は認証サーバーだけ、検証は各サービスが公開鍵で行う」という分離が自然にできます。

Cognito も内部で同じ構造(JWKS エンドポイントで公開鍵を配布)を取っています。

リフレッシュトークンをローテーションする理由

リフレッシュトークンを一度使ったら即座に削除し、新しいトークンを発行します(ローテーション)。

これにより、もし古いリフレッシュトークンが漏洩した場合でも、正規ユーザーが先に使っていればそのトークンは無効になっています。漏洩に気づけるトリップワイヤーとしても機能します。

Cognito との対比

このプロジェクトで実装した内容は、Cognito が User Pool の裏側でやっていることとほぼ対応します。

この実装 Cognito
createJWT / verifyJWT ID トークン・アクセストークンの発行・検証
SaveRefreshToken / ローテーション Refresh Token の管理
HandleGoogleCallback フェデレーション(外部 IdP 連携)
インメモリ Store Cognito User Pool のユーザーDB

マネージドサービスをいつ使い、いつ自作するかの判断は、中身を知っているかどうかで変わります。


動かし方

前提

  • Go 1.21 以上
  • Google Cloud Console で OAuth 2.0 クライアントを作成済みであること

セットアップ

git clone https://github.com/terry-writer/auth-server.git
cd auth-server

cp .env.example .env
# .env に GOOGLE_CLIENT_ID と GOOGLE_CLIENT_SECRET を記入

export $(cat .env | xargs)
go run .

動作確認

# ユーザー登録
curl -X POST http://localhost:8080/register \
  -H "Content-Type: application/json" \
  -d '{"email":"test@example.com","password":"password123"}'

# ログイン
curl -X POST http://localhost:8080/login \
  -H "Content-Type: application/json" \
  -d '{"email":"test@example.com","password":"password123"}'

# ユーザー情報取得(access_token を差し替えて使う)
curl http://localhost:8080/me \
  -H "Authorization: Bearer <access_token>"

# トークンリフレッシュ
curl -X POST http://localhost:8080/refresh \
  -H "Content-Type: application/json" \
  -d '{"refresh_token":"<refresh_token>"}'

今後の拡張候補

  • PKCE(Proof Key for Code Exchange)の実装
  • JWKS エンドポイント(/jwks.json)の追加
  • PostgreSQL によるストア永続化
  • Docker 対応
  • AWS へのデプロイ(ECS Fargate + ALB)

About

Go で JWT(RS256)と OAuth 2.0 / Google ログインをゼロから実装した認証サーバー

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages