kazu22002の技術覚書

PHPer, Golang, AWS エンジニアの日々

JWTが使えそうなため実装する前に調べてたことです

iOSのhttp2でのpush通知をやろうとした際に、JWTを使う必要がありいろいろと調べた内容です。

結構昔からある仕様ですが、触れる機会とこの技術はなんだろうという好奇心がなければ、気にしないですよね。

jwt.io

しらべてみてWebApiで活用が多いとのことで、自分のプロジェクトにも使用したいと思い、運用まで見据えて検討してみた内容です。

ちなみに運用自体はAPIのみ一ヶ月ぐらいの段階のため、実際に使えるのかどうかかなり不安な状態で検討した内容の記事を書いてます。

JWT

JSON Web Tokens」の略称で「ジョット」と読むそうです。

内容自体はIntroductionを読んだほうが詳しくなりますが、自分での理解としては

JSONの内容をハッシュ化して、改ざん検知、復号可能なトークンを作成し、認証や情報交換で使用できる仕組み。ぐらいで認識しています。

JSON Web Token Introduction - jwt.io

活用の事例として、WebAPIが多く見受けられるのは、システム自体をステートレスに構築できる点でかなり有用だと感じています。

セッションを使用しなくても、認証しているという情報が得られるため、より自由度の高いサーバー構築が可能になると感じています。

シングルサインオンとか簡単になりそうな印象です。

ただ運用を見据えるため、どのように使用するのがいいのか。セキュリティ的にやろうとしていることは正しいのか検討してみます。

どう使う?

今回はWebAPIでの使用を想定しています。

jwtのIntroductionにもある形のサーバーとクライアントの方式でやろうとしています。

サーバーへ認証APIからJWTを取得
↓
JWTを認証情報にその他APIを使用

認証情報はAuthorizationヘッダを使用して、送信するのが一般的みたいです。

「Authorization: Bearer

このあたりの流れはなんとなく理解しやすかったです。

じゃあ、受け取ったJWTってどこで持っておくのがいいの??

JWTの保持

正直わかりません。現在APIだけ提供しているため、実際に使用する側の処理を書いてないです。

たぶんcookieだと思ってます。

色々とほかの人のサイトをみて参考にみましたが、cookieかlocalstrageというのは納得しました。

christina04.hatenablog.com

一回作ったプッシュ通知のプログラムは動作し続けてるから、変数に保存するだけだったので、ステートレスとかどうでもいいやつでした。WEBだと運用違いますよね。(この辺りが上の人にはわからんのですよ。)

このあたりで自分の知識として認証の知識がないことをかなり自覚してきましたね。あぁ、まともにつくったことがなかったです。

そして次にセキュリティについて気になりました。

iOSのhttp2でのプッシュ通知の場合は、JWTの内容を自分で作成していたように見えたためセキュリティ的にも大丈夫そうな気がして安心してました。(必要な鍵ファイルをサーバに配置して作成)

ただWebAPIになったときに疑問が出てきました。

最初にAPIよりJWTの情報を取得しているため、内容にJWTの内容が載っている状態になります。まずこれは大丈夫なの??と疑問になったわけです。

JWTがもれた場合、どうなるの??

値が返却されるわけなので、JWTのトークンがわかるわけです。さすがにHTTPSで通信しているので、意識する必要があるのか。と思うかもしれないですが、気になったわけです。(JWTの値を取れている時点で認証できる人がみているわけですが、一応対策が気になります)

JWTの情報がもれた場合は、そのまま使うことが可能です。

認証として使用できるわけですが、これを防ぐ策としては時間制限を設けるしかないみたいです。

JWTの情報を作成するときに、トークンの有効時間が必要になっており、そのトークンが有効時間内かどうかをチェックしてます。

そのため、チェックがダメな場合はリフレッシュトークンとして再度JWTを取得する必要があります。

JWTが漏れた場合の対処はこれくらいしかないっぽいですね。

個人情報とかが多く、怖い場合はある程度短いほうがいいかもしれないです。

とりあえず、今回つくったのは1時間で設定しました。いまだに正しいのかわからないです。

どんな情報を持たせておくべき??

次に思ったのは、JWTを認証に使用した場合、なにをもたせればいいのか。

一応、認証で使用しようと思っているので、だれで認証しているかわかるようにしておく必要があります。

じゃあ、ログインしている人のID(システム採番のID)かな。と思ってましたが、これだとこのIDが漏れた時に修正のしようがなくなると思ったので、別の一意の文字列でユーザーが判断できる内容が適切ではないかな。と考えました。

このあたりは、JWTを復号して中身をみられても大丈夫な内容を持たせておけば大丈夫そうです。

公式サイトにも

つまり、トークン内に秘密情報を入れてはいけません

とのことです。みられても大丈夫な内容だけにしておきましょう。

便利そうだから使ってみる

そういうものでしょう。

ただなにも考えずに使用するほど無茶なことはできないので、利便性とリスクを検討した上でよさそうだ。という判断はしました。

ただフォーム認証より多くないので情報が少ないのは事実だと思いましたが、自分の認証の知識の少なさも今回で理解できましたね。

調べた時間やサンプルプログラムの作成で1週間ぐらいかかっています。

サンプルプログラムはgithubにあげれたらあげておきたいです。

まぁ、失敗してでもいいから先に進むよういろいろやってみましょう。

イノベイターには程遠いです。。。