JWTはただBase64をコートにしただけ——秒単位でオンラインで解読できます
JWTトークンは見かけは複雑に見えるが、ほとんどがBase64である。3つの部分構造を学び、主張を即座にデコードする方法、開発者が陥りやすい誤解(アルゴリズムの混同、ペイロードの秘密鍵、有効期限のバグ)を理解し、JWTとセッショントークンの使用タイミングを学ぼう。
あなたはネットワークタブを見つめています。リクエストヘッダーに「」という項目があります。 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c そして最初の反応は「これは何なのか?」です。
良いニュース:その文字列の大部分は単にBase64です。見かけが怖いブロブは、より神秘的なものだと装っており、実はそれほど神秘的ではありません。それを脱ぎ捨てましょう。
JWTが実際に何なのか
JSON Web Tokenは、3つのBase64urlエンコードされた部分がドットでつながったものです。
- ヘッダ – アルゴリズムとトークンタイプ(例:
{"alg":"HS256","typ":"JWT"}) - ペイロード – クレーム:ユーザーID、ロール、有効期限、サーバーが詰め込んだものなど
- サイン – 安全性を実行する部分
ヘッダーとペイロードは 暗号化されていません。Base64urlエンコードされているため、誰でもトークンを読むことができます——鍵は必要ありません。署名が唯一の防ぐもので、ペイロード内の1文字を変更すると無効になります。
現在ペイロードをデコードするには:2番目の部分(2つのドットの間)を取得し、 Base64デコーダーに投入し、そのままJSONが表示されます。これで終わりです。これが魔法のトリックです。
JWTを秒単位でデコードする方法
最も速い方法:トークンを JWTデコーダー に貼り付けます。IOToolsのサイトで、3つの部分を分割し、それぞれをデコードし、ヘッダーとペイロードをフォーマットされたJSONとして表示します——アカウントや設定、ログインなしで利用可能です。
典型的なペイロードで直ちに見られるもの:
sub– サブジェクト(通常はユーザーID)iat– 発行時刻(Unixエポック)exp– 有効期限時刻iss– 発行者- APIが詰め込んだカスタムクレーム:ロール、権限、プランレベルなど
もし、完全なデコーダーを構築する必要がない場合、ただトークンが有効期限切れかどうかを確認したいだけなら、 JWT有効期限チェックツール が、 exp クレームを読み取り、正確に残りの有効期間または終了時刻を教えてくれます。
JWTの3つの注意点が開発者を焼く
1. 検証を忘れてしまった有効期限
の exp フィールドはペイロード内の単なる数字です。サーバーがそれを検証する必要がありますが、多くの古いコードベースではそれが行われていない、またはタイムゾーン処理にバグがある場合があります。ユーザーが不思議にログアウトされる(または不思議に永遠にログインしている)場合、トークンをデコードし、 exp と現在のUnixタイムスタンプを比較してください。 有効期限チェックツール はこれを行います。
2. アルゴリズムの混乱
ヘッダーの alg フィールドは検証者が使うアルゴリズムを示します。いくつかの古いJWTライブラリは、 {"alg":"none"} を受容し、検証を完全にスキップし、署名を削除してペイロードをすべて無効と見なす場合があります。これは知られている攻撃です。常にライブラリが特定のアルゴリズムのリストを許容し、 none.
を拒否するように設定されていることを確認してください。 HS256 別のバリエーション:RS256(非対称)とHS256(対称)。公開鍵を知っている攻撃者は、ヘッダーを alg に変更し、公開鍵を秘密鍵として署名することでトークンを偽造できます。もしライブラリがヘッダーの
フィールドを無条件に信頼している場合です。解決策:ライブラリを「トークンが言うアルゴリズム」ではなく、明示的なアルゴリズムで構成してください。
3. ペイロード内のシークレット
ペイロードはBase64エンコードされており、暗号化されていないため、クライアントがそれを読むことができます(そして、HTTPでトークンをキャッシュした場合、誰でも読める可能性があります。ただし、すべての場所でHTTPSを使用しているはずです)。パスワード、PII、または内部システムの詳細をJWTクレームに保存しないでください。ペイロードは認可メタデータの場所であり、センシティブなデータを保存する場所ではありません。
自社アプリからトークンをデコードし、中身を確認してください。過去の開発者が何を詰め込んだか、驚くかもしれません。
JWTとセッショントークン:実際に何が違うのか
| 長年の議論。以下が直接比較です: | JWT | |
|---|---|---|
| セッショントークン | 状態がどこにあるか | トークン内(ステートレス) |
| サーバー側(データベースまたはメモリ) | 無効化 exp 難しい——トークンが有効期限まで有効 | ただしブロッキングリストを維持していない場合 |
| スケーラビリティ | 簡単——セッション記録を削除するだけ | 分散システムに最適;共有セッションストアは不要 |
| 必要 | クライアントがクレームを読める(暗号化されていない) | クライアントには隠蔽されている |
| ストレージリスク | localStorageはXSSに脆弱;httpOnlyクッキーはより安全 | httpOnlyクッキー(標準的なアプローチ) |
| トークンサイズ | 大きい——すべてのクレームをインラインで持ち運ぶ | 小さい——ただIDだけ |
| 最適な用途 | API、マイクロサービス、クロスドメイン認証 | 伝統的なサーバーレンダリングウェブアプリ |
どちらも普遍的に優れているわけではありません。JWTは複数サービス間でステートレス認証が必要な場合に優れています。セッショントークンは、完全なスタックを制御し、即時無効化(例:セキュリティ事件での「すべての場所からログアウト」)が必要な場合にシンプルです。
リアルなワークフローでのJWTデバッグ
JWTを使用するAPIで何かが壊れたときの典型的なシーケンスは以下の通りです:
- トークンをコピーする 失敗したリクエスト(認可ヘッダー、クエリパラメータ、またはクッキー——APIがそこに置く場所)から
- を JWTデコーダー に貼り付けて、原始的なクレームを確認する
- チェック
exp— トークンが有効期限切れですか?必要であれば、 有効期限チェックツール を使用して、頭の中でUnixタイムスタンプ計算を避けてください - チェック
issとaud— 発行者とアудィエンスがサービスが期待するものと一致しているか? - ヘッダーのアルゴリズムを確認する — サーバー設定と一致しているか?
- 署名形式を確認する — 3つの部分?2つの部分?改ざんされたトークンは時々2つの部分で署名がなく表示されます
ほとんどのJWTデバッグはステップ3で終わります。トークンは短いTTLで発行され、どこかでキャッシュされ、有効期限が過ぎてしまったのです。これは単調でよくあることです。
署名:重要な1つの部分
署名は次の通り計算されます: HMACSHA256(base64url(header) + "." + base64url(payload), secret)。サーバーがトークンを発行するときに生成されます。検証時には、同じハッシュを再計算し、比較します。ペイロードがまったく変更された場合(1文字でも)ハッシュが一致しなくなり、トークンは拒否されます。
これが、JWTをデコードしてクレームを読むことが安全で簡単である一方で、秘密を持たずに偽造することはできない理由です。Base64は衣装であり、署名はドアのロックです。
非対称アルゴリズム(RS256、ES256)の場合、署名鍵は認証サーバーにあり、決して外に出ません。検証鍵は、すべてのサービスが使用できる公開鍵です——共有秘密は必要ありません。これは、複数のサービスがトークンを検証する必要があるが、発行するのは1つのサーバーだけであるマイクロサービスのための正しいアーキテクチャです。
恵 スコアボードが到着しました!
スコアボード ゲームを追跡する楽しい方法です。すべてのデータはブラウザに保存されます。さらに多くの機能がまもなく登場します!
