自由気ままに書いちゃおう

好きなことをつらつらと・・・

【Github】JWT(JSON Web Token)について

Github Appを利用する際に、JWTについて調べる機会があったため、備忘を兼ねてになります。

JWTについて

JSON Web Token(JWT。「ジョット」と読むそうです。)は、Web上での情報の安全な伝達を可能にするためのコンパクトで自己完結型の方法です。

JWTは、認証や情報交換に広く使用されています。

以下はJWTの仕組みについてです。備忘を兼ねてになり、間違っておりましたら申し訳ないです。、。

ステップ1: JWTの構造

JWTは、.(ドット)で区切られた3つの部分から構成されています。

  1. ヘッダー(Header)
  2. ペイロード(Payload)
  3. 署名(Signature)

それぞれの部分はBase64エンコードされており、以下のような形式になります。

Base64Url(Header).Base64Url(Payload).Base64Url(Signature)

ステップ2: ヘッダー

ヘッダーは、トークンのタイプ(JWTであること)と、使用される署名アルゴリズム(例:HMAC SHA256やRSA)を宣言します。

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

このJSONはBase64UrlエンコードされてJWTの最初の部分を形成します。

ステップ3: ペイロード

ペイロード部分には、トークンに含めたい「クレーム(claims)」が含まれます。

クレームは、エンティティ(通常はユーザー)に関する情報と、追加のメタデータです。クレームには3種類あります。

  1. 登録済みのクレーム(Registered claims): 予約されたクレームで、トークンについての情報を提供します(例:iss(発行者)、exp(有効期限)、sub(主題)など)。
  2. 公開クレーム(Public claims): 衝突を避けるために、IANA JSON Web Token Registryに登録するか、衝突を避けるための名前空間を持つ必要があります。
  3. プライベートクレーム(Private claims): 送信者と受信者の間で合意されたクレームで、自由に定義できます。
{
  "sub": "1234567890",
  "name": "test user",
  "admin": true
}

このJSONもBase64UrlエンコードされてJWTの二番目の部分を形成します。

ステップ4: 署名

署名は、「ヘッダーのBase64エンコードされた値」と「ペイロードのBase64エンコードされた値」を合わせたものに、ヘッダーで指定されたアルゴリズムを使用して秘密鍵または公開鍵/秘密鍵ペアで署名します。

例えば、HS256アルゴリズムを使用する場合、以下のように署名が生成されます。

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

この署名は、トークンの改ざんを検出するために使用されます。

ステップ5: JWTの完成

最終的に、エンコードされたヘッダー、エンコードされたペイロード、署名をドットで連結してJWTが完成します。

以下は例です。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

ステップ6: JWTの使用

JWTは通常、HTTPヘッダーに含めて送信されます。認証が必要なリクエストを行う際に、AuthorizationヘッダーにBearerスキームを使用してJWTを含めます。

Authorization: Bearer <token>

サーバー側では、このトークンを受け取り、署名を検証し、ペイロードからユーザー情報を取得して、リクエストに対する権限をチェックします。

ステップ7: セキュリティの注意点

  • JWTはデコード可能なので、機密情報はペイロードに含めないようにしてください。
  • トークンの署名を検証することで、トークンの真正性を確認します。
  • HTTPSを使用してトークンの盗聴を防ぎます。
  • 適切な有効期限を設定して、トークンの長期使用を防ぎます。

以上です。