JWTは、ログイン後に使われる「中身が見える通行証」のようなトークンです。
ブラウザやアプリがJWTを持ってAPIへアクセスし、サーバーは署名を見て「改ざんされていないか」「期限内か」を確認します。
JWTは3つの部品でできている
JWTは、JSON Web Tokenの略です。名前だけ見るとむずかしそうですが、ざっくり言うと「情報を入れたトークンに、改ざんチェック用の署名を付けたもの」です。
JWTは主に、ヘッダー、本文(ペイロード)、署名の3つに分かれます。本文にはユーザーIDや権限、期限などを入れられますが、ここに入れた情報は暗号化されているとは限りません。
どんな種類のトークンか、どんな署名方法を使うかを表す部分。
ユーザーID、役割、有効期限など、サーバーが確認したい情報を入れる部分。
途中で書き換えられていないかをサーバーが確認するための部分。
ログイン後にJWTを受け取って使う
JWTは、ログインに成功したあとにサーバーから発行されることがあります。ブラウザやアプリはそのJWTを保存し、APIへリクエストするときに一緒に送ります。
API側のサーバーは、送られてきたJWTの署名や期限を確認します。問題がなければ「この人はログイン済み」と判断して、必要なデータを返します。
署名は「中身を隠す」ものではない
JWTで特に大事なのが、署名は暗号化とは別ものという点です。署名があると、サーバーは「このJWTは自分たちが発行したものか」「途中で本文が変えられていないか」を確認できます。
一方で、JWTの本文はBase64URLという形に変換されているだけで、見る方法を知っていれば内容を読めることがあります。つまり、署名は「改ざん検知」に役立つものですが、「秘密を隠す箱」ではありません。
JWTの本文は、利用者や第三者に見られる可能性がある前提で考える。
サーバーが署名を検証し、途中で書き換えられていないかを判断する。
パスワード、クレジットカード番号、秘密のメモなどはJWTに入れない。
期限切れと再発行もセットで考える
JWTは「一度発行したらずっと使える」状態にすると危険です。もしJWTが流出すると、その期限が切れるまで他の人に使われる可能性があるからです。
そのため、JWTには有効期限を入れ、期限が切れたら再ログインや再発行の仕組みで新しいトークンに切り替える設計がよく使われます。ログアウト時の扱いや、トークンをどこに保存するかも、サービスごとに慎重に決める必要があります。
古いJWTを長く使い続けないように、期限を持たせる。
通信中にトークンを盗み見されにくいように、暗号化された通信を使う。
ブラウザやアプリのどこに置くかで、攻撃されたときのリスクが変わる。
ここまでのまとめ
JWTは、ログイン後のAPI利用などで使われる署名付きトークンです。ヘッダー、本文、署名の3つでできていて、サーバーは署名を確認することで、改ざんされていないトークンかどうかを判断します。
JWTは「中身が見える通行証」。見られて困る秘密は入れず、署名、期限、保存場所をセットで考えるのが大切です。