📯

プッシュ通知の認可の仕組み ― Amazon Pinpointを活用したFCM HTTP v1の認可フロー

2024/04/17に公開

結論

認可のシーケンス図

はじめに

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コンソールから発行します。

  1. GCPコンソールの[IAMと管理] > [サービスアカウント] に移動する。
  2. 現在使用中のサービスアカウントを選択する
  3. 「キー」タブに移動する。
  4. 「鍵を追加」プルダウンから「新しい鍵を追加」を選択する。
  5. キーのタイプ「JSON」を選択する。
  6. 「作成」ボタンを押下する。

Amazon Pinpointにトークンをアップロード

次に、Pinpointに先ほど発行した秘密鍵をアップロードします。

  1. [Pinpoint] > [すべてのプロジェクト] > [pinpoint-] > [設定] > [プッシュ通知] > [プッシュ通知を編集] に移動する。
  2. Firebase Cloud Messaging (FCM)のデフォルトの認証タイプに「トークン認証情報 (推奨)
    」を選択する。
  3. 「ファイルのアップロード」を押下し、トークン(.jsonファイル)をアップロードする。

これでHTTP v1への移行は完了です。

HTTP v1方式の Amazon Pinpoint と FCM の間の認可の仕組み

さて、移行が完了したところで本題に入ります。
Amazon Pinpointは、FCMサービスを介して通知を送信する際に、GCPから発行されたトークン(サービスアカウントキー)を使用します。
OAuth2 セキュリティモデルに基づいて、有効期間の短いアクセストークン(Bearer Token)を生成し、これをHTTPリクエストのヘッダーに含めることで、FCMのAPIを安全に呼び出せます。
https://firebase.google.com/docs/cloud-messaging/migrate-v1?hl=ja

トークン(.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へのアクセスが許可されます。

認可フローの詳細

  1. トリガー発生 (通知リクエスト)
  • アプリケーション側でユーザーやシステムイベントが発生し、通知を送信する必要がある場合、Amazon Pinpoint(または他のクライアントアプリケーション)に通知リクエストが送信されます。
  1. アクセストークン生成要求
  • Amazon Pinpointは保存しているサービスアカウントの.jsonファイル(秘密鍵含む) を使用して、Google OAuth 2.0 エンドポイントに対してトークン生成リクエストを送信します。
  • リクエストはclient_emailとprivate_keyを使用して署名され、scopeパラメータにはhttps://www.googleapis.com/auth/firebase.messagingが含まれます。
  1. アクセストークン発行
  • 正常に認証されると、Google OAuth 2.0 サーバーは有効期間の短いアクセストークンを発行し、このトークンはHTTPリクエストのAuthorizationヘッダーにBearerトークンとして含まれます。
  1. 通知リクエスト送信 (Bearerトークン含む)
  • アクセストークンを取得した後、Amazon Pinpointは通知内容(メッセージ、タイトル、対象デバイスのトークンなど)を含むHTTP POSTリクエストをFCMのエンドポイントに送信します。
  • このリクエストは、Authorizationヘッダーに含まれるBearerトークンを使用して認証されます。
  1. 通知をデバイスに配信
  • FCMはリクエストを受け取り、指定された条件に基づいて対象のデバイスへ通知を配信します。
  1. ユーザーが通知を受け取る
  • 端末は通知を受信し、アプリケーションはそれをユーザーに表示します。

このフローにより、効率的かつ安全に通知を送信することができます。
Amazon PinpointやAmazon SNSなどのPaaSを利用しない場合、上記のような認可フローを独自のプッシュ通知サーバーに実装する必要があります。

おわりに

今回は、HTTP v1への移行手順と内部の認可フローの仕組みについて紹介しました。Amazon PinpointやAmazon SNSでは、認可フローを気にする必要がなく、秘密鍵をアップロードするだけで済むので、非常に便利ですね。

脚注
  1. OAuth 2.0は、Amazon Pinpointや他のクラウドサービスがユーザーのデータへのアクセスを管理するために用いる認証フレームワークです。このプロトコルは、ユーザーが自身のGoogleアカウント情報を直接暴露することなく、サービスアカウントを介してFCMに安全にアクセスするためのトークンを発行する機構を提供します。OAuth 2.0は多様な認証シナリオをサポートしており、Pinpointなどのサービスでは特に、サービスアカウントキーを用いた安全なAPI呼び出し(FCMへの通知リクエスト送信など)に活用されます。 ↩︎

  2. Bearerトークンは、Firebase Cloud Messaging (FCM)のセキュリティで重要なアクセストークンです。OAuth 2.0に基づいて生成され、このトークンを持つ者(bearer)は、HTTPリクエストのAuthorizationヘッダーにトークンを含めることで、許可された操作を行うことができます。例えば、Amazon PinpointからFCMへの通知送信リクエストにおいて、このトークンが正当なユーザーのアクセスを証明し、リクエストの認証を助けます。トークンは有効期間が限られており、セキュリティの維持のため定期的に更新が必要です。 ↩︎

Discussion