ユーザーアイコン

mizuko

約1か月前

0
0

Google Cloud Pub/Sub Webhook の JWT 認証実装

Google Cloud
JWT
セキュリティ

Google Cloud Pub/Sub の Push サブスクリプションからの Webhook を JWT で認証する方法。Google が推奨するセキュリティ対策として、従来のトークン検証から JWT 検証へ移行する。

実装手順:

  1. 必要なパッケージをインストール
pnpm add jsonwebtoken jwks-rsa pnpm add -D @types/jsonwebtoken
  1. JWT 検証サービスの実装
import * as jwt from 'jsonwebtoken'; import jwksClient from 'jwks-rsa'; // Google の公開鍵を取得するクライアント const client = jwksClient({ jwksUri: 'https://www.googleapis.com/oauth2/v3/certs', cache: true, cacheMaxAge: 10 * 60 * 1000, // 10分間キャッシュ rateLimit: true, jwksRequestsPerMinute: 10, }); // JWT 検証 async verifyPubSubJWT(token: string, expectedAudience: string) { const decoded = jwt.decode(token, { complete: true }); const key = await client.getSigningKey(decoded.header.kid); const publicKey = key.getPublicKey(); const verified = jwt.verify(token, publicKey, { algorithms: ['RS256'], audience: expectedAudience, // Webhook エンドポイントの完全 URL issuer: ['https://accounts.google.com', 'accounts.google.com'], }); // email_verified の確認も必須 if (!verified.email_verified) { throw new Error('Email not verified'); } return verified; }
  1. Webhook エンドポイントでの検証
// Authorization ヘッダーから Bearer トークンを取得 const authHeader = request.headers.authorization; if (!authHeader?.startsWith('Bearer ')) { throw new Error('JWT authentication required'); } const jwtToken = authHeader.substring(7); const audience = `https://${request.headers.host}/webhooks/gmail`; await verifyPubSubJWT(jwtToken, audience);

重要なポイント:

  • audience は Webhook URL と完全一致が必要
  • issuer は Google のアカウントサービス
  • email_verified が true であることを確認
  • 公開鍵は kid でキャッシュから取得