Go で OpenID Connect(OIDC)のログイン(Authorization Code Flow + PKCE)を実装する流れを整理します。ライブラリは golang.org/x/oauth2github.com/coreos/go-oidc の組み合わせが定番です。

全体の流れ

  1. Discovery/.well-known/openid-configuration からエンドポイントと JWKS を取得
  2. 認可リクエストstatenonce・PKCE の code_challenge を付けて IdP へリダイレクト
  3. コールバックstate を検証し、code を受け取る
  4. トークン交換code + code_verifier をトークンエンドポイントへ送り、IDトークンを取得
  5. IDトークン検証:署名(JWKS)・issaudexpnonce を検証
  6. ログインセッション確立

押さえるべきポイント

state(CSRF対策)

ランダム値を生成し、Cookie/セッションに保存。コールバックで一致を検証します。リダイレクト先 URL もここに紐づけると安全です。

nonce(リプレイ対策)

認可リクエストで生成した nonce を、IDトークンの nonce クレームと突き合わせます。

PKCE

code_verifier(ランダム)から code_challenge(S256ハッシュ)を作って認可リクエストに付与。コールバックで code_verifier をトークン交換に渡します。公開クライアントでも機密クライアントでも付けるのが現在の標準です。

IDトークン検証

go-oidc の Verifier を使い、JWKS による署名検証・aud(自分の client_id)・issexp を必ず検証します。手動検証の落とし穴は JWT検証の落とし穴 を参照。

実装スケッチ

provider, _ := oidc.NewProvider(ctx, issuerURL) // Discovery
oauth2cfg := oauth2.Config{
    ClientID:     clientID,
    ClientSecret: clientSecret,
    Endpoint:     provider.Endpoint(),
    RedirectURL:  redirectURL,
    Scopes:       []string{oidc.ScopeOpenID, "profile", "email"},
}
verifier := provider.Verifier(&oidc.Config{ClientID: clientID})

// 認可リクエスト(state / nonce / PKCE を付与)
url := oauth2cfg.AuthCodeURL(state,
    oidc.Nonce(nonce),
    oauth2.S256ChallengeOption(codeVerifier),
)

// コールバック:code 交換 → IDトークン検証
tok, _ := oauth2cfg.Exchange(ctx, code, oauth2.VerifierOption(codeVerifier))
rawID := tok.Extra("id_token").(string)
idToken, _ := verifier.Verify(ctx, rawID) // 署名・aud・iss・exp を検証

まとめ

OIDC 実装の肝は「state / nonce / PKCE を省略しない」「IDトークンを必ず検証する」の2点です。仕組みの背景は OpenID Connect とは を、運用は 企業SSO完全ガイド を参照してください。