iOSのプッシュ通知送信時のAPNs接続の認証に、今までは証明書を使っていましたが、代わりにトークン認証を利用することができるようになったので軽く調べてみました。
メリット
今までの証明書をサーバーに置く方式では証明書の期限が切れたら更新する必要がありましたが、トークン方式では期限が無いため更新が不要です。なのでうっかり更新を忘れていてプッシュ通知が送れなくなっているということが無くなります。
また、期限が切れる度に新しい証明書に入れ替える手間も省けます。
トークン認証利用に必要な手順
- Apple Developerの証明書の作成画面に
Apple Push Notification Authentication Key (Sandbox & Production)
という選択肢が増えているので、それを選択して秘密鍵を作成 - プッシュ通知送信時に、この秘密鍵を使って署名したトークンを
authorization
ヘッダに乗せ、apns-topic
ヘッダで送信先AppのBundleId
を指定してPOST
(その他のヘッダ内容、通知内容(payload)を入れるbodyは従来と変わらないのでドキュメント参照。)
※2015/12に公開された新しいAPNs Provider APIでのみトークン認証に対応しているようです。
APNs Provider APIについてはこちらが参考になりました
http://qiita.com/itosho/items/2402df4de85b360d5bd9
※トークン認証では秘密鍵生成時にAppIDを指定しないため、apns-topic
ヘッダでの送信先Appの指定が必須になっています。
つまり従来の証明書利用時のようにAppIDごとに作成をしなくても良くなりますが、どのように運用するかは検討が必要かもしれません。
※秘密鍵は再ダウンロードすることはできないので、バックアップ必須です。
実際に送信まで試したわけではないので、間違いがあればご指摘いただけると助かります。
トークンの生成
トークンとしてJSON Web Token(JWT)を生成して利用します。
JSON Web Tokenについてはこちらが参考になりました。
http://qiita.com/kaiinui/items/21ec7cc8a1130a1a103a
では、どのようなJSONフォーマットのデータに署名すればよいかというと、ドキュメントによるとこんな感じでした。
{
"alg": "ES256",
"kid": "ABC123DEFG"
}
{
"iss": "DEF123GHIJ",
"iat": 1437179036
}
alg
- 署名アルゴリズム。ES256のみ対応。詳細はドキュメントに。
kid
- Apple Developerの証明書管理画面で作成した秘密鍵のID。同画面から確認可能。(Key ID)
iss
- デベロッパのチームID(Apple Developer管理画面から確認可能)
iat
- トークンが生成された時刻(Unixtimestamp)
※iat
のタイムスタンプが過去1時間以内でない場合はエラーになるため、定期的にトークンを生成することを推奨しているようです。
その他
- 基本的に生成した秘密鍵は無期限なので一度作成したらずっと使えるが、盗まれた可能性がある場合などは管理画面からRevokeできます。
##参考
- Apple Developer Guide - Local and Remote Notification Programming Guide
https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/APNsProviderAPI.html#//apple_ref/doc/uid/TP40008194-CH101-SW1