web-dev-qa-db-ja.com

JavaサーバーからiOSデバイスにプッシュ通知を送信する

私はプッシュ通知をApple Javaで書かれたサーバーからデバイスに送信するという一見標準的なタスクを持っています。私は過去にそれをしたことがないので、チュートリアルに行きましたAppleドキュメント。

1)APNプロバイダーAPI は、サーバーからプッシュ通知を送信するためのプロトコルがHTTP/2であると主張しています。その方法を説明するチュートリアルを見つけることができませんでした(ほとんどの場合、私が最初にそれを実行するのではなく、最も人気のあるツール/ライブラリへの参照のためであることを示すためのサインとしてそれらを望みました)。バイナリプロトコルを使用してプッシュ通知を送信する方法を教えるいくつかのチュートリアル( Ray Wenderlichチュートリアル おそらく最も引用されている)を見つけました。ほとんどのGitHubプロジェクトでも同様に使用されます(たとえば、「プッシュ通知 シミュレータキット Ray Wenderlichチュートリアルから」、人気のある「 pushmeup "Ruby = gem、非常に人気のある notnoop/Java-apns ライブラリなど)。今では、Apple docs has a section for binaryそれを述べるプロバイダーAPI

レガシーバイナリインターフェイスでは、プロバイダーサーバーがこの付録で説明されているバイナリAPIを使用する必要がありました。すべての開発者は、リモート通知プロバイダーサーバーを、APNsプロバイダーAPIで説明されているより機能的で効率的なHTTP/2ベースのAPIに移行する必要があります。

これは間違いなく、私は新しい開発にバイナリAPIを使用するべきではないように思えます...バイナリAPIは、「デッド」デバイストークン用の個別のフィードバックサービスの使用(定期的なポーリング)を必要とするため(または、ブロックされる場合があります)彼らは言う)、新しいHTTP/2 APIはこの情報を個々のリクエストへの応答として提供しますが、これは可動部分が少ないように見えます。

HTTP/2に関しては、比較的人気があるJavaライブラリ CleverTap/apns-http2 がありますが、Jetty HTTP/2クライアントを使用します。 1つ動作する 起動する必要があります ブートクラスパスにALPN jarを含むJVM、およびそのjarはおおよそ対応します JDKバージョンでは1対1 (つまり、開発は1.8.0u92を使用し、プロダクションは1.8.0u91を使用しているため、異なるjarが配置されているはずです。これは、一般的に私にとって非常に脆弱な構成のように見え、私の場合は適用が難しいようです(各開発者は独自のVM + common dev VM + test server + prod)-すべてのマシンで1つのバージョンをフリーズすることは価値がないと思いますが、これらは動作しません時間の経過とともに分岐します。すべてがJDK 8を使用していることはわかっていますが、マイナーバージョンは私の制御不能です。ALPNjarのこの必要性は、JDK 9がリリースされるまで(そして広く採用されるまで)、1年以上を意味します、それはJettyとNettyとokhttp3の場合で、Javaライブラリ。

2)これでは不十分であるかのように、Apple docsで説明されている2つの認証スキームもあります。証明書(「古いスタイル」)と [〜#〜] jwt [〜#〜] の使用の比較。証明書によるアプローチは試行錯誤されていますが、ドキュメントからは証明書を再生成する必要があるようです毎年JWTはそうではありませんが(正確に言うと、JWTは1時間ごとに自動的に再生成されるため、アプリケーションに組み込まれ、忘れられるなどの手動による管理アクションが不要になることを願っています)。私にとってのJWTは

トークンを作成したら、 アプリ配布ガイド のユニバーサルプロバイダートークン署名鍵の作成で説明されているように、秘密鍵で署名する必要があります。

問題は、そのガイドにそのようなセクションやタイトルなどがないことです。おそらく、このステップは非常に単純ですが、特にiOSのセキュリティを実際に体験したことはなく、一般的に暗号化の経験もほとんどないので、ここで何かを見逃してしまうと思います。私はiOS開発者に助けを求めることができますが、実用的なチュートリアルが見つからない場合、このアプローチが十分に成熟しているかどうかさえわかりません。

したがって、私の質問は最終的に(いずれかを選択)です:

  • 何か不足していますか?Appleのガイドラインに従う方法があり、解決策は合理的に簡単ですか?
  • バイナリプロトコルが「すぐに」終了する可能性はどのくらいありますか?
  • バイナリプロトコルまたはHTTP/2を選択する必要がありますか?
  • 後者の場合、JWTを使用して追求する必要がありますか、それとも証明書を使用する方が現実的ですか?
  • たぶん、状況(主にHTTP/2で)は、他のいくつかの言語/サーバープラットフォームではるかに良くなりますか?私がiOSプッシュを送信するためだけに別のサービスを用意することを考えているかもしれません。

長いテキストでごめんなさい。

3
starikoff

Java(JDK固有のjetty alpn-boot jarを使用する代わりに)でHTTP/2を操作する別の方法があります:ALPNをサポートするネイティブSSLプロバイダーを使用します。 bootclasspathにalpn-boot JARなしで完全に移行します。netty-tcnative( githubdocs )によって実装されます。ApachePortable Runtime(APR)がインストールされている必要があります。 OpenSSL(これもインストールする必要があり、バージョン1.0.2以降である必要があります)に対してリンクされます。Fedoraと他のすべてのLinuxディストリビューションでは異なります。 BoringSSL に対して静的にリンクされたフレーバーがあります(OpenSSL fork with 「コードフットプリントの削減」)。

Tomcatと一緒に使用することはできません(AFAIKはTomcatの部分的なポート tcnative であり、衝突するため)。

機能する私の設定は次のようになります:

  1. APRとOpenSSLをインストール。
  2. pushy ライブラリを依存関係として指定しました(バージョン0.7.3)。それは再帰的にalpn-api、netty(4.1.1.Final)の一部、およびその他の必要な依存関係をもたらしました。
  3. 依存関係としてnetty-tcnativeを指定(opensslとboringsslの両方のバージョンが機能し、これまでのところboringsslを選択)、バージョン4.1.1.Final。

pushyライブラリは証明書の使用を必要としますが、JWTサポートは 途中 です。

また、 Laivが言ったように 、GCM(FCM?Firebase?)は、両方のAndroidおよびiOSデバイスにプッシュを送信できます。私が理解している限り、 iOSでは、すべてのApple固有のパーツが必要です(証明書など)。JWTサポートについては不明です。AndroidとiOSのサポートを個別に実装したくない場合は、必ず検討するオプションです。

1
starikoff

いくつかのプッシュサーバーを実装し、そのすべてが古いタプル "socket-certificate"。In Java(1.5-1.7)

証明書を使用するには、いくつかの欠点があります。たとえば、環境ごと(テスト、プロなど)に1つ必要です。あなたはそれらを管理する上で整然とする必要があります、そうでなければプロで間違った証明書で終わることは非常に簡単です。または、更新を忘れます(期限切れも)。

ソケットに関連して、このアプローチでは、ファイアウォールで特定の範囲のポートを開く必要があります。

通信のプロトコル全体に関連しています。メッセージをプッシュした後、あなたはほとんど情報を得ません。メッセージで何が起こったかを理解するのは困難です。唯一の方法は、応答のキューからメッセージを取得することです。注文したキューは保証されません。 APNSがその上に応答を送信するときも同様です。それはまったく起こらないかもしれません。

GCM(HTTP経由で実行されるGoogleクラウドメッセージ)と比較すると、APNSの「ソケット証明書」は...

私の提案は、HTTP 2-JWTに集中することですプロトコル。これは、クライアント/サーバー通信におけるセキュリティの非常に一般的な実装です。 APNSソケットと証明書を探すよりも、http2とJWTに関する多くのリファレンスが見つかります。

最近、JWTを介したセキュリティが一般的に実装されています。コミュニティからの完全なサポートがあります。

さらに、もし彼らが現在の実装へのサポートを落とすことを計画しているなら、なぜそれを試みることを敢えてするのかなぜ時間とお金を2回使うのですか?

予防する。 HTTP2の実装-JWTアプローチは、さらなるコードレビューやリファクタリングからあなたを救います。いずれにせよ、それはやるべき仕事ですので、後で行うより早く行う方がよいでしょう。

ライブラリCleverTapに関連しています。だれもあなたがあなた自身のクライアントを実装するのを止めません!ニーズと要件に合わせて。

これは、現在のエンジンのケースです。すべてのサードパーティの実装を破棄し、独自に構築しました。これまでのところ、完全に機能し続けることはわかっています... Appleがサービスを停止するまで。

(まだHTTP2に移行していない場合-JWTは時間とお金によるものです)

おそらく代替案があります。 Google Firebase Cloud Messageはマルチプラットフォームです。したがって、同じサービスからAndroidおよびiOsデバイスにメッセージをプッシュできます。 HTTPおよびAPIキー(トークン)を介して動作します。私はあなたに一見することを勧めます。

1
Laiv