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 からのコールバック処理 |
golang-jwt/jwt などのライブラリを使えば数行で実装できます。あえて使わなかったのは、署名・検証の内部構造(Base64URL エンコード、PKCS1v15 署名、有効期限検証)を自分の手で確かめるためです。
ライブラリは正しく使うために、中で何が起きているかを知っておく必要があります。
HS256(共通鍵)は実装がシンプルですが、検証する側にも秘密鍵を渡す必要があります。RS256 は秘密鍵で署名し、公開鍵で検証するため、マイクロサービス構成で「発行は認証サーバーだけ、検証は各サービスが公開鍵で行う」という分離が自然にできます。
Cognito も内部で同じ構造(JWKS エンドポイントで公開鍵を配布)を取っています。
リフレッシュトークンを一度使ったら即座に削除し、新しいトークンを発行します(ローテーション)。
これにより、もし古いリフレッシュトークンが漏洩した場合でも、正規ユーザーが先に使っていればそのトークンは無効になっています。漏洩に気づけるトリップワイヤーとしても機能します。
このプロジェクトで実装した内容は、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)