JWT

API | IT用語集

この用語をシェア

JWTとは

JWT(JSON Web Token)は、安全にユーザー情報を送信するためのコンパクトで自己記述的なトークンです。RFC 7519として標準化されており、認証とデータ交換において広く使用されています。JWTは、情報をJSONオブジェクトとして安全に送信でき、デジタル署名によって検証可能です。

JWTの主要な特徴

  • コンパクト:URLセーフなBase64エンコーディング
  • 自己記述的:必要な情報がトークン内に含まれる
  • 検証可能:デジタル署名による完全性の保証
  • ステートレス:サーバーで状態を保持する必要がない
  • 相互運用性:異なるドメイン間でも使用可能

JWTの構造

JWTは、ピリオド(.)で区切られた3つの部分から構成されます:

Header.Payload.Signature

完全なJWTの例

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IuOCv+ODg+OBquKAnEpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Headerの詳細

ヘッダーには、トークンの型と署名アルゴリズムが含まれます。

Header例

{
  "alg": "HS256",
  "typ": "JWT"
}

主要なアルゴリズム

アルゴリズム 説明 用途
HS256 HMAC with SHA-256 対称鍵署名
RS256 RSA Signature with SHA-256 非対称鍵署名
ES256 ECDSA with SHA-256 楕円曲線デジタル署名
none 署名なし 非本番環境のみ

Payloadの詳細

ペイロードには、クレーム(claim)と呼ばれる情報が含まれます。

Payload例

{
  "sub": "1234567890",
  "name": "田中太郎",
  "email": "tanaka@example.com",
  "iat": 1516239022,
  "exp": 1516325422,
  "iss": "https://example.com",
  "aud": "https://api.example.com"
}

標準クレーム

クレーム 説明
iss Issuer(発行者) "https://example.com"
sub Subject(主体) "1234567890"
aud Audience(対象者) "https://api.example.com"
exp Expiration Time(有効期限) 1516325422
iat Issued At(発行時刻) 1516239022
nbf Not Before(有効開始時刻) 1516239022
jti JWT ID(一意識別子) "abc123"

Signatureの詳細

署名は、ヘッダーとペイロードの改ざんを検証するために使用されます。

HMAC SHA256での署名生成

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)

RSA SHA256での署名生成

RSASHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  privateKey
)

JWTの実装例

Node.js(jsonwebtoken)

const jwt = require('jsonwebtoken');

// JWT生成
const payload = {
  sub: '1234567890',
  name: '田中太郎',
  email: 'tanaka@example.com',
  iat: Math.floor(Date.now() / 1000)
};

const secret = 'your-secret-key';
const token = jwt.sign(payload, secret, { expiresIn: '1h' });

console.log(token);

// JWT検証
try {
  const decoded = jwt.verify(token, secret);
  console.log(decoded);
} catch (err) {
  console.error('Invalid token:', err.message);
}

Python(PyJWT)

import jwt
import datetime

# JWT生成
payload = {
    'sub': '1234567890',
    'name': '田中太郎',
    'email': 'tanaka@example.com',
    'iat': datetime.datetime.utcnow(),
    'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1)
}

secret = 'your-secret-key'
token = jwt.encode(payload, secret, algorithm='HS256')

print(token)

# JWT検証
try:
    decoded = jwt.decode(token, secret, algorithms=['HS256'])
    print(decoded)
except jwt.ExpiredSignatureError:
    print('Token has expired')
except jwt.InvalidTokenError:
    print('Invalid token')

Java(jjwt)

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;

// JWT生成
String secret = "your-secret-key-must-be-at-least-256-bits";
Key key = Keys.hmacShaKeyFor(secret.getBytes());

String token = Jwts.builder()
    .setSubject("1234567890")
    .claim("name", "田中太郎")
    .claim("email", "tanaka@example.com")
    .setIssuedAt(new Date())
    .setExpiration(new Date(System.currentTimeMillis() + 3600000)) // 1時間
    .signWith(key, SignatureAlgorithm.HS256)
    .compact();

System.out.println(token);

// JWT検証
try {
    Claims claims = Jwts.parserBuilder()
        .setSigningKey(key)
        .build()
        .parseClaimsJws(token)
        .getBody();
    
    System.out.println("Subject: " + claims.getSubject());
    System.out.println("Name: " + claims.get("name"));
} catch (JwtException e) {
    System.out.println("Invalid token: " + e.getMessage());
}

JWTの使用例

認証フロー

  1. ログイン:ユーザーが認証情報を送信
  2. JWT発行:サーバーがJWTを生成して返却
  3. リクエスト:クライアントがJWTをAuthorizationヘッダーに含めて送信
  4. 検証:サーバーがJWTを検証してリクエストを処理

Authorization ヘッダー

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IuOCv+ODg+OBquKAnEpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

JWTのセキュリティ

セキュリティ考慮事項

  • 秘密鍵の管理:対称鍵は絶対に秘匿する
  • 有効期限の設定:適切な有効期限を設定する
  • HTTPS必須:JWTの送信時はHTTPSを使用
  • 機密情報の除外:パスワード等の機密情報はペイロードに含めない
  • 適切なアルゴリズム:セキュアな署名アルゴリズムを使用

一般的な攻撃と対策

攻撃 対策
None アルゴリズム攻撃 none アルゴリズムを無効化
鍵の混同攻撃 アルゴリズムの厳密な検証
リプレイ攻撃 短い有効期限と nonce の使用
JWT の改ざん 署名の厳密な検証

JWTの利点

  • ステートレス:サーバーで状態を保持する必要がない
  • スケーラビリティ:負荷分散が容易
  • 相互運用性:異なるドメイン間でも使用可能
  • モバイルフレンドリー:クッキーに依存しない
  • JSON形式:JavaScript等での扱いが容易

JWTの欠点

  • 取り消し困難:有効期限まで無効化できない
  • サイズ:セッションIDと比較してサイズが大きい
  • 機密情報:ペイロードはBase64エンコーディングのみ
  • 時刻同期:サーバー間で時刻の同期が必要

JWT vs セッション

特徴 JWT セッション
状態管理 ステートレス ステートフル
スケーラビリティ 高い 低い
セキュリティ 署名に依存 サーバー管理
取り消し 困難 容易
サイズ 大きい 小さい

JWTの活用場面

  • API認証:RESTful APIの認証トークン
  • シングルサインオン:複数アプリケーション間でのSSO
  • マイクロサービス:サービス間の認証
  • モバイルアプリ:ネイティブアプリの認証
  • 情報交換:異なるシステム間でのデータ交換

JWTツール

  • JWT.io:JWT デコーダー・検証ツール
  • jwt-cli:コマンドラインJWTツール
  • Auth0 Debugger:JWT デバッグツール

関連技術

  • JWS:JSON Web Signature
  • JWE:JSON Web Encryption
  • JWK:JSON Web Key
  • OAuth 2.0:認可フレームワーク
  • OpenID Connect:認証プロトコル

関連Webサイト

この用語についてもっと詳しく

JWTに関するご質問や、システム導入のご相談など、お気軽にお問い合わせください。

カテゴリ

API IT用語集