【iOS】Firebase Cloud Messagingで利用するAPNs認証キー・証明書の作り方

以前開発したときは、APNs証明書だけだったのに知らぬうちに2つの方法ができていたので備忘録です。

# そもそもAPNsとは？
Apple Push Notification Service(以下、APNs)は、iOSやtvOS、MacOS上で実行されているアプリケーションに対して開発者側から通知を送るためのAppleによるサービスのことを指します。
誤解されがちなのは、Firebase Cloud Messaging(以下、FCM)などの通知を行えるサービスと各アプリケーションが1対1で繋がっているようにとらわれがちですが、Appleデバイスを対象に通知を送付する際は必ずAPNsを介して送付されています。

当たり前ですが、APNsに対してどんなリクエストでも送れてしまったら意図しない通知がユーザーの手元に届いてしまいますので、サーバー側とAPNs間のセキュアな通信を担保するために証明書または、認証キーが必要です。

# 認証キーと証明書
現在は、Appleデバイスに対してPush通知を送るために用いる認証方法が2つ存在しています。
記事によってはどちらかのみ記載している例があるため、それぞれ記載します。

## Apple Push Notification Service SSL
今まで、Push通知を行う際に用いられてた証明書タイプの認証方法です。
アプリごとに証明書を発行する必要があり、発行から1年間の有効期限付きです。
また、SandboxとProductionそれぞれの証明書を発行する必要があります。
Sandboxでは上手く行っていたのに、AdhocやReleaseのアプリに通知が飛ばないとかは、証明書の登録漏れとかが原因だったりすることが多いです。

## Apple Push Notification Authentication Key
こちらが新しい方法。(新しいといってもだいぶ前からなんですが、Push関連やることが少なかったので浦島太郎でした。)
アプリごとに証明書を用意する必要がなくベンダー共有の認証キーです。
有効期限がないため、更新する手間がないのがメリットです。

基本的には、こちらの認証方法が現在では推奨されています。

# 発行方法
## Apple Push Notification Authentication Key
![スクリーンショット 2020-04-04 19.18.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114168/75585ccd-c326-74c4-c8bd-976e991fecf6.png)
Apple Developer Programのページにアクセスし、左側の「Program Resources」以下に表示されている「Certtificates, Identifiers & Profiles」をクリックします。
![スクリーンショット 2020-04-04 19.25.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114168/6f65cf51-4d34-35ea-e48c-cdd3a885bbfd.png)
次に「Keys」にアクセスし、Keys横のプラスボタンをクリックします。
![スクリーンショット 2020-04-04 19.26.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114168/d95e77a6-2c1d-65e2-4467-d5f825ccd80a.png)
Keyの登録画面になるので、Keyの名称とAPNsのチェックボックスにチェックを入れてContinueをクリックします。
再度確認画面が表示されるのでRegisterをクリックするとKeyを生成することができます。
![スクリーンショット 2020-04-04 19.29.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114168/f70e816e-6562-1e10-a4bb-720cbfda5ac4.png)
生成後、p8形式のキーのダウンロードが可能になります。生成されたキーは**1度だけ**ダウンロードできます。
1度ダウンロードした後、再ダウンロードすることはできませんので注意が必要です。

## Apple Push Notification Service SSL
こちらが古い方法。
Authentication Keyと異なりいくつかのステップがあります。(Developer Programのページで完結しないのが面倒)![スクリーンショット 2020-04-04 20.10.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114168/413f2c01-6e10-3212-9b18-0572fd284903.png)


### 1.Certificate Signing Requestの発行
Certificate Signing Reques(以下、CSR)とは、証明書を発行するときに認証局に対してメッセージのことです。
CSRの発行は、手持ちのMacのキーチェーンアクセスアプリから行います。
![スクリーンショット 2020-04-04 19.37.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114168/34d7af53-d622-c96a-c8fb-156e4144a78c.png)
キーチェーンアクセスから**証明書アシスタント**→**認証局に証明書を要求**を選択します。
![スクリーンショット 2020-04-04 19.47.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114168/d5a23b68-fba6-75f1-365e-fc851f0a57b1.png)
上記の画面が表示されるので、メールアドレスと通称部分に任意の内容を記入します。
要求の処理では、**ディスクに保存**と**鍵ペア情報を指定**にチェックを入れます。
入力とチェックを入れたら続けるを選択します。
**CertificateSigningRequest.certSigningRequest**の保存先の選択が求められるので、任意のディレクトリに保存しましょう。
![スクリーンショット 2020-04-04 19.50.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114168/8b8a8bc2-6d49-933e-dee2-7a045a474e11.png)
鍵ペア情報の選択が求められますが、こちらは初期値のままで大丈夫です。
![スクリーンショット 2020-04-04 19.51.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114168/9c3050fd-3881-d79a-e1af-ef32ea20ed1d.png)
完了すると上記画面が表示されます。
以上でCSRの発行は完了です。

### 2. 証明書の生成
![スクリーンショット 2020-04-04 19.18.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114168/75585ccd-c326-74c4-c8bd-976e991fecf6.png)
認証キー同様に、Apple Developer Programのページにアクセスし、左側の「Program Resources」以下に表示されている「Certtificates, Identifiers & Profiles」をクリックします。
![スクリーンショット 2020-04-04 20.03.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114168/e9a08c3a-c30f-e05e-cb68-11c356a449be.png)
次に「Certificates」にアクセスし、Certificates横のプラスボタンをクリックします。
![スクリーンショット 2020-04-04 20.04.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114168/705b7c5a-9855-30b7-a493-a268be12677d.png)
Create a New Certificate画面が開きますので、Servicesの項目配下にある**Apple Push Notification service SSL**にチェックを入れます。
証明書にはSandbox環境だけへの接続を認可するものとSandboxとProduction環境どちらへの接続を認可するものがあります。
後者のキーだけでも開発用APNsキーと本番用APNsキーを兼用することはできますが、基本的にはSandbox用とProduction用は別々に発行したほうが良いと思います。
![スクリーンショット 2020-04-04 20.09.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114168/a680e7ea-a2d4-d755-5934-52dbd1f660f3.png)
Platformと通知を利用するアプリのAppIDの選択が求められるので、通知を利用するAppIDを探し選択し次に進みます。
![スクリーンショット 2020-04-04 20.10.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114168/419200b0-799d-efb8-5d27-73c28da06556.png)
先程発行したCSRファイルの登録が求められるので、Choose Fileから発行したCSRファイルを選択します。
![スクリーンショット 2020-04-04 20.12.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114168/ec9acbec-bf26-97d8-3f27-a53bdd6cbf2b.png)
次へ進むと証明書のダウンロードが可能になります。生成した証明書をダウンロードしましょう。
cer形式の証明書がダウンロードできます。
### 3. p12形式に変換する
Firebase Cloud Messagingでは、cer形式の証明書のままではアップロードできませんので手元でp12形式で書き出す必要があります。
![スクリーンショット 2020-04-04 20.16.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114168/9106ab32-0318-77fd-ef5a-a175da14b639.png)
ダウンロードしたcer形式の証明書をダブルクリックし、キーチェーン.appに証明書を追加します。
![スクリーンショット 2020-04-04 20.17.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114168/99ef46ce-dd44-45eb-496b-aff686aa2463.png)
追加した証明書上で**右クリック**→**「キー名」を書き出す**を選択します。
![スクリーンショット 2020-04-04 20.22.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114168/206f653f-7b52-ad85-042f-490389a58644.png)
証明書の名称、保存先の入力選択が求められるので任意の内容に設定します。フォーマットは「個人情報交換(.p12)」のままで大丈夫です。
![スクリーンショット 2020-04-04 20.23.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114168/03de7858-28f1-001b-cc86-b8b2fa0672f1.png)
保存時にパスワード設定が求められます。任意のパスワードを設定して書き出しましょう。
OKを押すとまれにキーチェーンアクセスからのパスワード入力を求められることがありますが、Macのログインパスワードを入力すればOKです。
任意のパスにp12形式の証明書が書き出されていれば成功です。

# Firebaseに認証キー・証明書をアップロードする
![スクリーンショット 2020-04-04 20.26.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114168/07fbe6ca-3c0d-da29-62ec-c0ade4807270.png)
Firebaseのコンソールを開き、Push配信を行うプロジェクトを選択します。
選択後、**プロジェクトの概要**横に表示されている歯車アイコンをクリックし、設定ページを表示します。
次にクラウドメッセージングの設定項目を選択し、**iOSアプリの設定**から証明書をアップロードすることができます。
Push通知を送るには、認証キー・証明書どちらかをアップロードすればFCMからAPNsを通して、アプリがインストールされている端末に対して通知を送ることが可能になります。

重ねてにはなりますが証明書を用いる場合、開発環境用と本番環境用それぞれの証明書をアップロードする必要があります。
片方だけアップロードしてもどちらかの環境では通知が届かないということが発生しますので注意が必要です。

# おわりに
FCMでは、現在認証キーを用いることが推奨されていますが未だに証明書形式でのFCMの利用方法などが記載されている事例が見られたので、改めて2つの方法があるよーということを書かせていただきました。
駆け足にはなりましたが参考になりますと幸いです。