エラーメッセージ
oidc: expected audience "api-client" got ["web-client"]
coreos/go-oidc (Go) — IDTokenVerifier.Verify
このエラーの意味
ID トークンは正しいプロバイダーによって署名されていますが、その `aud` クレームに、`oidc.Config` で設定した `ClientID` が含まれていません。go-oidc は、ID トークンは発行先のクライアントに対してのみ有効であるという OpenID Connect のルールを実装しています。引用符で囲まれた最初の値は設定した `ClientID`、リストはトークンのオーディエンスです。
発生する理由
別のクライアントの ID トークンが転送されている
よくあるフロントエンドが自身の ID トークンをバックエンドの API に送り、API がそれを API 自身のクライアント ID で検証しています。ID トークンは、それを要求したクライアントのためのものです。API はアクセストークンを受け取るべきです。
設定したクライアント ID が間違っている
よくある別のアプリ登録や環境のクライアント ID をコピーした場合や、ID の代わりにクライアントシークレットの名前を使った場合です。正しい値はトークンの `aud` で確認できます。
アクセストークンを ID トークンとして検証している
ときどきJWT のアクセストークンは、`aud` にクライアント ID ではなく API の識別子を持っています。`IDTokenVerifier` はデフォルトでクライアント ID をチェックするため、オーディエンスを自分でチェックしない限り、アクセストークンの検証は失敗します。
修正方法
- 1.
ユーザーをログインさせたアプリのクライアント ID を使う
ID トークンでは、トークンの発行先であるクライアント ID を正確に設定してください。
go verifier := provider.Verifier(&oidc.Config{ ClientID: os.Getenv("OIDC_CLIENT_ID"), // the client the user signed in to; must equal the token's aud }) idToken, err := verifier.Verify(ctx, rawIDToken) - 2.
API のアクセストークンでは、API のオーディエンスを自分でチェックする
`SkipClientIDCheck` が無効にするのは、組み込みのクライアント ID の比較だけです。代わりに API の識別子を明示的にチェックしてください。オーディエンスの検証そのものを省略してはいけません。
go // Verifying a JWT access token for an API: check signature/issuer/expiry here, // then check the API audience yourself. verifier := provider.Verifier(&oidc.Config{SkipClientIDCheck: true}) tok, err := verifier.Verify(ctx, rawAccessToken) if err != nil { return err } if !slices.Contains(tok.Audience, "https://api.example.com") { return errors.New("token not issued for this API") }