Memo

メモ > 技術 > サービス: AmazonSNS > iOS: p8証明書

iOS: p8証明書
p8証明書については、以下で解説されている。 iOSでのPush通知について | 株式会社ウイングドア https://wingdoor.co.jp/blog/ios%E3%81%A7%E3%81%AEpush%E9%80%9A%E7%9F%A5%E3%81%AB%E3%81%A4%E3%81%84%E... 以下のように紹介されている。 ・Apple Developer Programで登録しているApple IDで管理している全てのアプリで使用可能。 ・本番環境と開発環境で同じ証明書を使用できる。 ・有効期限は無期限。 ・証明書は一度しかダウンロードできない。(再度作成することは可能。) ・一つのApple IDで2つまでしか証明書を作成できない。 p8証明書を使うと、Androidと同じく「永続的なキーが発行されるが、使用するには都度トークンを発行する必要がある」となる。 トークンの発行については、AmazonSNSを使うことで容易に扱えるようになる。 p12の方が証明書の影響範囲が限定的というメリットはあるので、必ずしもp8証明書にしなければならないわけでは無い。 ただしAppleとしてはp8証明書を推奨しているようなので、まずはp8証明書の利用を検討するといい。 Should we use p8 Auth Key or P12 for APNs? | by Kieu Van Phuoc | Medium https://kieuvanphuoc.medium.com/should-we-use-p8-auth-key-or-p12-for-apns-e5737938fde9 Apple Developer Programの「Keys」からキーを作成できるみたい。 curlで実際にプッシュ通知を送信するコードも以下で紹介されている。 iOSのPush通知でAPNsとの連携を証明書と認証キーでそれぞれやってみた - つばくろぐ @takamii228 https://takamii.hatenablog.com/entry/2020/07/13/190027 コマンド(curl)でPushテストする方法(iOS) #Swift - Qiita https://qiita.com/dolfalf/items/2b65c77d11c4e8dbdd9a 以下なども参考になりそう。 iOSのプッシュ通知がp8認証キーに対応しました - ニフクラ mobile backend(mBaaS)お役立ちブログ https://blog.mbaas.nifcloud.com/entry/2021/04/08/202417 iOS プッシュ通知の実装に必要な「p12形式の証明書」と「 p8形式の鍵」について #iOS - Qiita https://qiita.com/kokogento/items/405703f3177ebd2e0320 APNs証明書(p8形式)の発行方法 - FANSHIPサポートガイド https://support.fanship.jp/hc/ja/articles/900006538803-APNs%E8%A8%BC%E6%98%8E%E6%9B%B8-p8%E5%BD%A2%E... ■証明書の取得 APNs証明書(p8形式)の発行方法 - FANSHIPサポートガイド https://support.fanship.jp/hc/ja/articles/900006538803-APNs%E8%A8%BC%E6%98%8E%E6%9B%B8-p8%E5%BD%A2%E... iOS プッシュ通知の実装に必要な「p12形式の証明書」と「 p8形式の鍵」について #Firebase - Qiita https://qiita.com/kokogento/items/405703f3177ebd2e0320 Certificates, Identifiers & Profiles → Keys → + Key Nameを「refirio」とし、さらに下の一覧にある「Apple Push Notifications service (APNs)」にチェックを入れた。 キーは「1アカウントにつき2つまでしか作れない」「案件ごと、アプリごと、本番&検収環境、などで分けることができない」なので、単純に「refirio」という名前にした。 「Continue」をクリック。 確認画面が表示されるので「Register」をクリック。 鍵のダウンロードができるので「Download」をクリックして保存。(「AuthKey_XXXXXXXXXX.p8」という名前だった。) さらに「Done」をクリックして完了。 Keysの画面に戻り、発行済みのキーとして以下が表示された。 KEY ID: XXXXXXXXXX SERVICES: 1 NAME: refirio Apple Developer Programにログインし、「メンバーシップの詳細」から「チームID」を確認しておく。 チームID: YYYYYYYYYY ■JWTトークンの発行 JWT(JSON Web Token)を使った認証を行う。 (Androidでも google/apiclient の内部では同様の仕組みが使われているみたい。) JWTについては以下のページなどを参照。 初心者向けJWT講座:JSON Web Tokenを使った認証の仕組み https://zenn.dev/collabostyle/articles/b08c7f29a2e94c まずは、Composerで必要なライブラリをインストール。
$ composer require firebase/php-jwt
以下のとおりプログラムを作成。(今回は firebase-jwt.php としておく。)
<?php require 'vendor/autoload.php'; use Firebase\JWT\JWT; use Firebase\JWT\Key; // 必要な情報を設定 $keyId = 'XXXXXXXXXX'; // Apple DeveloperのKey ID $teamId = 'YYYYYYYYYY'; // Apple DeveloperのTeam ID $p8FilePath = 'AuthKey_XXXXXXXXXX.p8'; // p8ファイルのパス // p8証明書の読み込み $privateKey = file_get_contents($p8FilePath); if (!$privateKey) { die('p8ファイルが見つかりません。'); } // JWTのヘッダーとペイロードを設定 $now = time(); $payload = [ 'iss' => $teamId, // チームID 'iat' => $now // JWTの発行時刻 ]; $headers = [ 'alg' => 'ES256', // アルゴリズム 'kid' => $keyId // キーID ]; // JWTトークンの生成 $jwt = JWT::encode($payload, $privateKey, 'ES256', $keyId); echo "JWTトークン: " . $jwt . PHP_EOL;
プログラムを実行すると、以下のとおりJWTトークンが発行された。
$ php firebase-jwt.php JWTトークン: eyJ0eXAiOi0000000000bGciOiJFUzI1NiIsImtpZCI6Ikc5MjNOWTRXNVkifQ.eyJpc3MiOiJENVpRUVk5OFpMIiwiaWF0IjoxNzI5ODUwOTMzfQ.kySqsqu5SkhS0WhKWmgou3SUf7188n3AHRvlK1_72aMlw6n3m019pk0cEVQuypx2M8nUr8U4K1cf5rO7Br9zIw
このJWTトークンを使って、以下のコマンドでプッシュ通知を送信できる。
$ curl -v -d '{"aps":{"alert":{"title":"[送信タイトル]","body":"[送信メッセージ]"},"sound":"default"}}' -H "Content-Type: application/json" -H "apns-topic: [アプリのID]" -H "apns-priority: 10" -H "authorization: bearer [JWTトークン]" --http2 https://api.development.push.apple.com/3/device/[デバイストークン]
具体的には、以下のように実行する。
$ curl -v -d '{"aps":{"alert":{"title":"テスト","body":"これはp8ファイルによる送信です。"},"sound":"default"}}' -H "Content-Type: application/json" -H "apns-topic: net.refirio.pushtest1" -H "apns-priority: 10" -H "authorization: bearer eyJ0eXAiOi0000000000bGciOiJFUzI1NiIsImtpZCI6Ikc5MjNOWTRXNVkifQ.eyJpc3MiOiJENVpRUVk5OFpMIiwiaWF0IjoxNzI5ODUwOTMzfQ.kySqsqu5SkhS0WhKWmgou3SUf7188n3AHRvlK1_72aMlw6n3m019pk0cEVQuypx2M8nUr8U4K1cf5rO7Br9zIw" --http2 https://api.development.push.apple.com/3/device/d6cb5af49500000000002425020838f4d4792c2de946bce49ad2... * Trying 17.188.143.66:443... * Connected to api.development.push.apple.com (17.188.143.66) port 443 * ALPN: curl offers h2,http/1.1 * Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH * TLSv1.2 (OUT), TLS handshake, Client hello (1): * CAfile: /etc/pki/tls/certs/ca-bundle.crt * CApath: none * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Request CERT (13): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Certificate (11): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384 * ALPN: server accepted h2 * Server certificate: * subject: C=US; ST=California; O=Apple Inc.; CN=api.development.push.apple.com * start date: Apr 24 18:16:30 2024 GMT * expire date: Apr 10 00:00:00 2025 GMT * subjectAltName: host "api.development.push.apple.com" matched cert's "api.development.push.apple.com" * issuer: CN=Apple Public Server RSA CA 12 - G1; O=Apple Inc.; ST=California; C=US * SSL certificate verify ok. * using HTTP/2 * [HTTP/2] [1] OPENED stream for https://api.development.push.apple.com/3/device/d6cb5af49500000000002425020838f4d4792c2de946bce49ad2... * [HTTP/2] [1] [:method: POST] * [HTTP/2] [1] [:scheme: https] * [HTTP/2] [1] [:authority: api.development.push.apple.com] * [HTTP/2] [1] [:path: /3/device/d6cb5af49500000000002425020838f4d4792c2de946bce49ad240be4f19c9b2] * [HTTP/2] [1] [user-agent: curl/8.3.0] * [HTTP/2] [1] [accept: */*] * [HTTP/2] [1] [content-type: application/json] * [HTTP/2] [1] [apns-topic: net.refirio.pushtest1] * [HTTP/2] [1] [apns-priority: 10] * [HTTP/2] [1] [authorization: bearer eyJ0eXAiOi0000000000bGciOiJFUzI1NiIsImtpZCI6Ikc5MjNOWTRXNVkifQ.eyJpc3MiOiJENVpRUVk5OFpMIiwiaWF0IjoxNzI5ODUwOTMzfQ.kySqsqu5SkhS0WhKWmgou3SUf7188n3AHRvlK1_72aMlw6n3m019pk0cEVQuypx2M8nUr8U4K1cf5rO7Br9zIw] * [HTTP/2] [1] [content-length: 114] > POST /3/device/d6cb5af49500000000002425020838f4d4792c2de946bce49ad240be4f19c9b2 HTTP/2 > Host: api.development.push.apple.com > User-Agent: curl/8.3.0 > Accept: */* > Content-Type: application/json > apns-topic: net.refirio.pushtest1 > apns-priority: 10 > authorization: bearer eyJ0eXAiOi0000000000bGciOiJFUzI1NiIsImtpZCI6Ikc5MjNOWTRXNVkifQ.eyJpc3MiOiJENVpRUVk5OFpMIiwiaWF0IjoxNzI5ODUwOTMzfQ.kySqsqu5SkhS0WhKWmgou3SUf7188n3AHRvlK1_72aMlw6n3m019pk0cEVQuypx2M8nUr8U4K1cf5rO7Br9zIw > Content-Length: 114 > < HTTP/2 200 < apns-id: 5371130C-0127-0D02-AA12-41C29AA8EE5B < apns-unique-id: 7def9a2f-df7f-e8fc-778c-04337c567bf9 < * Connection #0 to host api.development.push.apple.com left intact
■AmazonSNSへの登録 AmazonSNS → プッシュ通知 → PushTest1-APNS-Dev → 編集 認証方法: トークン 署名キー: (上の手順で取得したp8ファイル。) 署名キーID: XXXXXXXXXX チームID: YYYYYYYYYY バンドルID: net.refirio.pushtest1 「変更の保存」ボタンをクリック。 PushTest1-APNS-Dev の画面に戻る。 しばらくしてページを再読み込みすると、 認証方法: Certificate 証明書の有効期限: 2025-11-24T04:45:55Z と表示されていた部分が 認証方法: Token AppleバンドルID: net.refirio.pushtest1 AppleチームID: YYYYYYYYYY と表示されるようになった。 この状態でAmazonSNS経由でプッシュ通知を送り、アプリに届くことを確認する。

Advertisement