JWTデコーダー
JSON Web Tokenをデコードして検査。ヘッダー、ペイロード、クレーム、有効期限を表示。
// Decode JWT (without verification)function decodeJWT(token) {const [header, payload] = token.split('.').slice(0, 2);return {header: JSON.parse(atob(header)),payload: JSON.parse(atob(payload))};}// Using jsonwebtoken library// npm install jsonwebtokenconst jwt = require('jsonwebtoken');const decoded = jwt.decode(token);const verified = jwt.verify(token, secret);
関連ツール
JWTとは?
JWT(JSON Web Token、「ジョット」と発音)はデジタルパスポートのようなものです。当事者間で情報を安全に送信するためのコンパクトで自己完結的な方法です。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4ifQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
意味不明に見える?実は、ドットで区切られた3つのbase64エンコードされた部分です!
JWTが存在する理由:
- ステートレス認証 - サーバーにセッションを保存する必要がない
- クロスドメイン - 異なるサービス間で動作
- 自己完結型 - すべての情報がトークン自体に含まれる
- コンパクト - ヘッダーやURLで送信できるほど小さい
JWT構造の解説
JWTは3つの部分で構成されています:ヘッダー.ペイロード.署名
1. ヘッダー(赤い部分)
{
"alg": "HS256",
"typ": "JWT"
}
トークンタイプと署名アルゴリズムを示します。
2. ペイロード(紫の部分)
{
"sub": "1234567890",
"name": "山田太郎",
"admin": true,
"iat": 1516239022,
"exp": 1516242622
}
実際のデータ(「クレーム」と呼ばれる)を含みます。
3. 署名(青い部分) トークンが改ざんされていないことを検証します。
誰でもJWTを読めます! ペイロードはただのbase64エンコードであり、暗号化されていません。JWTに機密データ(パスワード、クレジットカード)を絶対に入れないでください。
一般的なJWTクレーム
登録クレーム(標準)
| クレーム | 名前 | 説明 |
|---|---|---|
iss | 発行者 | トークンを作成した人 |
sub | 主題 | トークンが誰/何についてか |
aud | 対象者 | トークンを受け入れるべき人 |
exp | 有効期限 | トークンが期限切れになる時(Unixタイムスタンプ) |
iat | 発行日時 | トークンが作成された時 |
JWT認証の仕組み
1. ユーザーが資格情報でログイン
┌──────┐ ユーザー名/パスワード ┌──────┐
│ユーザー│ ──────────────────────→│サーバー│
└──────┘ └──────┘
2. サーバーがJWTを作成して返す
┌──────┐ JWTトークン ┌──────┐
│ユーザー│ ←──────────────────────│サーバー│
└──────┘ └──────┘
3. ユーザーがリクエストごとにJWTを送信
┌──────┐ Authorization: Bearer JWT ┌──────┐
│ユーザー│ ────────────────────────────→│サーバー│
└──────┘ └──────┘
なぜこれがセッションより優れているか:
- サーバーは何も保存する必要がない
- 複数のサーバー(マイクロサービス)間で動作
- 水平スケーリングが容易
JWTセキュリティの考慮事項
JWTはデフォルトでは暗号化されていません! 誰でもペイロードをデコードして読むことができます。署名は改ざんを防ぐだけです。
一般的なJWTの脆弱性:
1. Noneアルゴリズム攻撃
{"alg": "none"}
攻撃者がアルゴリズムを「none」に設定して署名検証をバイパス。 修正: サーバーで常にアルゴリズムを検証。
2. シークレットキーの弱さ 「secret」や「password」のような弱いシークレットはブルートフォースできる。 修正: 256ビット以上のランダムキーを使用。
3. 有効期限なし
期限切れにならないトークンはセキュリティリスク。
修正: 常に exp クレームを設定(短期間:15分〜1時間)。
セキュリティベストプラクティス:
- 強力でランダムなシークレットキーを使用(最低256ビット)
- トークンは短命に(アクセストークンは15分)
- 長いセッションにはリフレッシュトークンを使用
- 常にHTTPSを使用
- サーバー側ですべてのクレームを検証
JWT vs セッションクッキー
| 機能 | JWT | セッションクッキー |
|---|---|---|
| 保存 | クライアント | サーバー |
| スケーラビリティ | 優秀(ステートレス) | セッション共有が必要 |
| セキュリティ | localStorageだとXSS脆弱 | CSRF脆弱 |
| モバイル | 実装が簡単 | クッキー処理が必要 |
| 失効 | 難しい(期限切れを待つ) | 簡単(ストアから削除) |
JWTを使うべき場合:
- シングルページアプリケーション(SPA)
- モバイルアプリケーション
- マイクロサービスアーキテクチャ
セッションを使うべき場合:
- 従来のWebアプリケーション
- 即時失効が必要な場合
- 機密アプリケーション(銀行)