プッシュ通知の認可の仕組み ― Amazon Pinpointを活用したFCM HTTP v1の認可フロー
結論
認可のシーケンス図
はじめに
2024年6月20日までにFirebase Cloud MessagingのレガシーAPIが廃止されるため、HTTP v1 APIへの移行が必要とアナウンスがありました。
これを受けて、2023年11月17日にHTTP v1に対応したAmazon Pinpointを利用して、対応作業を行いました。
実施した内容は、必要なトークンを発行し、それをPinpointにアップロードするというものです。
Pinpointは認可フローの多くを自動化してくれるため便利ですが、この機会にFCMの新しい認証方式(HTTP v1 API)について調査しました。なお、この記事ではレガシー認証方式には触れません。
この記事でわかること
- HTTP v1への移行手順
- FCMの認可フロー
- FCMの役割
- Pinpointの役割
HTTP v1への移行手順
まず、認可の仕組みを説明する前にHTTP v1への移行手順を説明します。後続で説明する認可フローの前提条件でもあるためです。なお、クラスメソッドさんの記事はAmazon SNSでの対応に関するものですが、Pinpointでの対応にも非常に参考になりました。
GCPコンソールにてトークンを発行する
最初に、Amazon Pinpointで使用するためのトークンをGCPコンソールから発行します。
- GCPコンソールの[IAMと管理] > [サービスアカウント] に移動する。
- 現在使用中のサービスアカウントを選択する
- 「キー」タブに移動する。
- 「鍵を追加」プルダウンから「新しい鍵を追加」を選択する。
- キーのタイプ「JSON」を選択する。
- 「作成」ボタンを押下する。
Amazon Pinpointにトークンをアップロード
次に、Pinpointに先ほど発行した秘密鍵をアップロードします。
- [Pinpoint] > [すべてのプロジェクト] > [pinpoint-] > [設定] > [プッシュ通知] > [プッシュ通知を編集] に移動する。
- Firebase Cloud Messaging (FCM)のデフォルトの認証タイプに「トークン認証情報 (推奨)
」を選択する。 - 「ファイルのアップロード」を押下し、トークン(.jsonファイル)をアップロードする。
これでHTTP v1への移行は完了です。
HTTP v1方式の Amazon Pinpoint と FCM の間の認可の仕組み
さて、移行が完了したところで本題に入ります。
Amazon Pinpointは、FCMサービスを介して通知を送信する際に、GCPから発行されたトークン(サービスアカウントキー)を使用します。
OAuth2 セキュリティモデルに基づいて、有効期間の短いアクセストークン(Bearer Token)を生成し、これをHTTPリクエストのヘッダーに含めることで、FCMのAPIを安全に呼び出せます。
.json
)の役割
トークン(GCPコンソールで発行したトークンには、サービスアカウントの詳細が含まれており、FCMのアクセストークンを発行する際に使用されます。ファイルの構造は以下の通りです。
{
"type": "service_account",
"project_id": "project-id",
"private_key_id": "key-id",
"private_key": "-----BEGIN PRIVATE KEY-----\n...",
"client_email": "email-id@project-id.iam.gserviceaccount.com",
"client_id": "client-id",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/email-id%40project-id.iam.gserviceaccount.com"
}
- type: ファイルのタイプであり、「service_account」が指定されます。
- project_id: GCPのプロジェクトIDで、サービスアカウントが所属するプロジェクトを指します。
- private_key_id: 私有キーの一意識別子。
- private_key: サービスアカウントの秘密鍵。OAuth 2.0[1]で使用されるアクセストークンを生成する際に利用されます。
- client_email: サービスアカウントのメールアドレス。このメールアドレスは、API呼び出し時にGoogleのサーバーで認証される識別子として機能します。
- client_id: サービスアカウントのクライアントID。
- auth_uri: 認証を行うためのURI。
- token_uri: トークンをリクエストするためのURI。
- auth_provider_x509_cert_url: 認証プロバイダのX.509証明書のURL
- client_x509_cert_url: サービスアカウントのX.509証明書のURL。
認可フローで特に重要なのが、秘密鍵(private_key) です。
この秘密鍵がOAuth 2.0 アクセストークンを生成し、FCMサーバーへのAPIリクエストを行う際に、HTTPヘッダーにBearerトークン[2]として添付されます。これにより、リクエストが正当であることが保証され、APIへのアクセスが許可されます。
認可フローの詳細
- トリガー発生 (通知リクエスト)
- アプリケーション側でユーザーやシステムイベントが発生し、通知を送信する必要がある場合、Amazon Pinpoint(または他のクライアントアプリケーション)に通知リクエストが送信されます。
- アクセストークン生成要求
- Amazon Pinpointは保存しているサービスアカウントの.jsonファイル(秘密鍵含む) を使用して、Google OAuth 2.0 エンドポイントに対してトークン生成リクエストを送信します。
- リクエストはclient_emailとprivate_keyを使用して署名され、scopeパラメータにはhttps://www.googleapis.com/auth/firebase.messagingが含まれます。
- アクセストークン発行
- 正常に認証されると、Google OAuth 2.0 サーバーは有効期間の短いアクセストークンを発行し、このトークンはHTTPリクエストのAuthorizationヘッダーにBearerトークンとして含まれます。
- 通知リクエスト送信 (Bearerトークン含む)
- アクセストークンを取得した後、Amazon Pinpointは通知内容(メッセージ、タイトル、対象デバイスのトークンなど)を含むHTTP POSTリクエストをFCMのエンドポイントに送信します。
- このリクエストは、Authorizationヘッダーに含まれるBearerトークンを使用して認証されます。
- 通知をデバイスに配信
- FCMはリクエストを受け取り、指定された条件に基づいて対象のデバイスへ通知を配信します。
- ユーザーが通知を受け取る
- 端末は通知を受信し、アプリケーションはそれをユーザーに表示します。
このフローにより、効率的かつ安全に通知を送信することができます。
Amazon PinpointやAmazon SNSなどのPaaSを利用しない場合、上記のような認可フローを独自のプッシュ通知サーバーに実装する必要があります。
おわりに
今回は、HTTP v1への移行手順と内部の認可フローの仕組みについて紹介しました。Amazon PinpointやAmazon SNSでは、認可フローを気にする必要がなく、秘密鍵をアップロードするだけで済むので、非常に便利ですね。
-
OAuth 2.0は、Amazon Pinpointや他のクラウドサービスがユーザーのデータへのアクセスを管理するために用いる認証フレームワークです。このプロトコルは、ユーザーが自身のGoogleアカウント情報を直接暴露することなく、サービスアカウントを介してFCMに安全にアクセスするためのトークンを発行する機構を提供します。OAuth 2.0は多様な認証シナリオをサポートしており、Pinpointなどのサービスでは特に、サービスアカウントキーを用いた安全なAPI呼び出し(FCMへの通知リクエスト送信など)に活用されます。 ↩︎
-
Bearerトークンは、Firebase Cloud Messaging (FCM)のセキュリティで重要なアクセストークンです。OAuth 2.0に基づいて生成され、このトークンを持つ者(bearer)は、HTTPリクエストのAuthorizationヘッダーにトークンを含めることで、許可された操作を行うことができます。例えば、Amazon PinpointからFCMへの通知送信リクエストにおいて、このトークンが正当なユーザーのアクセスを証明し、リクエストの認証を助けます。トークンは有効期間が限られており、セキュリティの維持のため定期的に更新が必要です。 ↩︎
Discussion