WebPush Notification、使ってみたくないですか?
最近のアプリ界隈ですと、何かと通知やらLocalStorageへのキャッシュやら、 Service Worker を用いたい、という場合があると思います。
ところがまず WebPush やりたい!と言ってもクライアント・サーバを両方とも考慮して実装を考えなければならないので、例えばクライアント側、サーバ側、という風に実装を分けた場合、容易にこの開発をすすめることは難しくなります。 というか一人でもだいぶ混乱します。
なので、サーバ側・クライアント側のサンプルを用意して、これを用いて開発の初期段階をすすめていただきたい、というのがこの記事の要旨です。
実装はどこ?
サーバ側(Clojure):https://github.com/MokkeMeguru/tcs-notification/tree/test
クライアント側(React+TypeScript):https://github.com/MokkeMeguru/tcc-notification-debug/tree/test
使い方は両方ともREADMEを見てください。Docker-Composeで解決するので、すぐに試すことができると思います。
技術的な話
WebPush のぱっとした説明が欲しい。
WebPush はサーバ、クライアント、そしてプッシュサーバに構成される技術です。
全体の流れ
登録
Push通知
サーバ側のやること
まず、公開鍵・秘密鍵のペアを生成します。
(この辺りは WebPush-<Programming Language> の機能を使いましょう。私のサーバサイドプログラムでは WebPush-Java を用いて公開鍵、秘密鍵のペアを得ることができるようになっています。)
次に、クライアント側に公開鍵を晒します。するとクライアント側で なんかしてくれて クライアント情報、
{:endpoint <url>
:keys {:p256dh <str>
:auth <str>}}
というようなデータがもらえるので、こいつを例えば User-id などと組み合わせて DB に保存しておきます。(私のプログラムではDBを使わず直接ソースコードに書き込んでいます。)
Push 通知を送りたくなったならば、これも WebPush-<Programming Language> のライブラリに従ってデータを組み立てて、Push Server に送信します。
クライアント側でやること
サーバ側から 公開鍵 が送られてくるので、こいつからのデータを受け取る、という旨のメッセージを Push サーバに送りつけます。
Push サーバが受け取ると、endpoint という URL が貰えるので、こいつとクライアントの情報 (p256dh , auth) をまとめてサーバに送りつけます。
ここでクライアントの User-id User-name あたりも送信できると、 サーバ側がすごく楽になります 。
Push サーバから通知データが送られてきたら、そいつを拾ってきて、 Service Worker 内で データを読みます。そして Service Worker から自分の通知欄に向けて、通知データを送ります。
Push サーバ がやること
クライアント から サーバの公開鍵 が送られてくるので、ふーん、って顔をして公開鍵を持っておいて、クライアントの受け取り口であるURL、 endpoint を返します。
次にサーバ側から 秘密鍵で署名されたJWT、 公開鍵、通知データが送られてくるので、本当にこいつをクライアントに送っていいか確認します。
確認が取れたら、endpoint へ通知データをポイします。
脆弱性
簡単に要約すると、
不正な クライアント情報_2 を登録されると大変なことになる
ぜひ読んでほしい資料
Googleの WebPush に関する説明
https://developers.google.com/web/fundamentals/push-notifications/web-push-protocol