JWTとは?仕組みと安全な使い方
JWT(JSON Web Token)は認証情報をBase64エンコードされたJSON形式で安全に伝送するためのオープン標準(RFC 7519)です。現代のWebアプリ・APIの認証で広く採用されています。
JWTの3つの構成要素
JWTは「ヘッダー」「ペイロード」「署名」の3パートをドット(.)でつなげた文字列です。ヘッダーはトークンタイプ(typ: JWT)と署名アルゴリズム(alg: HS256など)をBase64URLエンコードしたもの、ペイロードはクレーム(sub・iss・exp・iatなどの標準クレームとカスタムクレーム)、署名はヘッダーとペイロードをシークレットキーでHMAC計算したものです。JWT DecoderではこれらをリアルタイムにデコードしてJSON形式で表示します。HS256(HMAC-SHA256)は共有シークレット方式で、RS256(RSA-SHA256)は公開鍵/秘密鍵方式です。公開鍵を配布するJWKS(JSON Web Key Set)エンドポイントはOAuth 2.0・OpenID Connectで標準的に使われます。
expクレームと有効期限の確認
ペイロードのexp(expiration)クレームはUnixタイムスタンプで有効期限を表します。JWT Decoderでは有効期限の残り時間を人間が読める形で表示し、期限切れの場合は赤く警告します。「なぜかAPIが401を返す」という場面でトークンのexpを確認するのが基本的なデバッグ手順です。iat(issued at)クレームはトークンが発行された時刻、nbf(not before)クレームはその時刻以前には使えないという制限を表します。アクセストークンの有効期間は一般的に15分〜1時間程度に短く設定し、リフレッシュトークンで長期認証を管理するパターンがセキュリティの観点から推奨されます。JWT Decoderでexpとiatの差分からトークンの寿命を計算して設計の確認に使えます。
JWTはなぜBase64なのか
JWTのヘッダーとペイロードはBase64URL(URL-safe Base64)でエンコードされているだけで、暗号化はされていません。つまりJWTは「偽造できない」が「中身は見える」という特性があります。機密情報(パスワード・クレジットカード番号・個人を特定できる情報)はペイロードに含めてはいけません。改ざん検知には署名(第3パート)を使います。暗号化が必要な場合はJWE(JSON Web Encryption)という別の規格を使います。JWT Decoderのようなツールで誰でもデコードできることを念頭に置き、ペイロードには最小限のクレームだけ含める設計が安全です。userIdのような識別子はOKですが、メールアドレスや氏名などの個人情報はペイロードに含めないことを推奨します。
JWTのデバッグとよくある問題
「署名が無効」「トークンが期限切れ」「issuerが一致しない」はJWT関連のよくあるエラーです。JWT Decoderでトークンをデコードしてiss(issuer)・aud(audience)・exp・iatを確認することで問題を特定できます。オフラインで動作するためトークンを外部サービスに送信するリスクがありません。よくある問題のもう一つは「アルゴリズムの混同」で、サーバーがHS256を期待しているのにRS256で署名されたトークンを渡すとエラーになります。ヘッダーのalgクレームで使用アルゴリズムを確認してください。また「audクレームの不一致」は複数サービス(APIサーバーAとBなど)でJWTを共用する際に発生しやすく、audで用途を絞ることでセキュリティを高めつつデバッグも容易になります。