0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JWTとは何なのか調べてみた

Posted at

JWTについて

アクセス制御、認証、認可で使われるJWTについて理解を深めたいと思い記事にしました。

そもそもJWTとは?

  • JSON Web Tokenの略
  • WebアプリやAPIで「認証・認可情報を安全に持ち運ぶためのコンパクトなトークン」
  • 自己完結型(トークン自体に必要な情報が詰まっている)のが特徴
  • 属性情報(Claim)をJSONデータ構造で表現したトークン仕様を指す。

1.JWTの全体構造

まずJWTの全体の構造について簡単な図で説明したい。

体系イメージ

┌────────────┐
│ JWT (JSON Web Token) ← 仕様の“総称” │
└─────┬───────┘
      │
      ├── JWS (JSON Web Signature) = 署名付きトークン
      │    └─ header.payload.signature という見慣れた3部構成
      │
      └── JWE (JSON Web Encryption) = 暗号化付きトークン
           └─ header.暗号化鍵.IV.暗号化payload.認証タグ など5部構成
  • JWT:JSON形式のクレームを安全委持ち運ぶための規格全体。
  • JWS:JWTを「署名」で保護する方式(改ざん検知のみ)
  • JWE:JWTを「暗号化」で保護する方式(秘匿+改ざん検知)

2.JWTのルール

実際のJWTのルールについて大きく3つに分けて説明する

① 構造に関するルール

  • 以下の例(JWS)のように.(ピリオド)で区切る。
header.payload.signature
  • Header・PayloadはBase64URLエンコードされる(改行や+ではなく-_を使うURL安全な形式)
  • SignatureはHeader+Payloadを秘密鍵で署名したもの

② クレーム(Claim)に関するルール

 Payloadに入れるデータ(クレーム)には予約語がある

  • iss(issuer): 発行者

  • sub(subject): 主体(ユーザーIDなど)

  • aud(audience): 対象

  • exp(expiration): 有効期限(秒単位UNIXタイム)

  • iat(issued at): 発行時刻

    → これらの予約クレーム名は仕様で定義済み。自由に追加するカスタムクレームもOK

③ セキュリティに関するルール

  • 秘密情報はPayloadに入れない(暗号化されていないので誰でも読める)。
  • 署名アルゴリズムを固定する(Headerのalgを信頼しない。サーバー側で強制する)。
  • 有効期限を必ず設定する(無期限トークンは危険)。
  • HTTPS通信必須(平文HTTPで送らない)。
  • トークンの失効管理(必要ならブラックリスト、短命アクセストークン+リフレッシュトークン)。

3.典型的な使われ方・利用用途

ここでは簡単ではあるが、典型的な使われ方や利用されるシーンについて説明したい。

使われ方

  1. ユーザーがログイン→サーバーがJWTを発行
  2. クライアント(ブラウザやアプリ)がJWTを保存(CookieやLocalStrageなど)
  3. APIアクセス時にJWTを送信(Authorizationヘッダなど)
  4. サーバー側は署名検証してユーザーを特定

利用用途

  • OAuth 2.0、OpenID Connectなどの認証プロトコルにおけるトークン
  • Cokkieを使うのが難しいマイクロサービスやモバイルアプリでのセッション管理
  • シングルサインオン(SSO)での認証
  • RESTful APIの認証
  • ステートレス認証

4.JOSEとは?

JWTには暗号化や署名に関してのルールがある。

この大事なルールを定めた規格をJOSE(JSON Object Signing and Encryption)という。

そして、署名に関するルールをJWS、暗号化に関するルールをJWEと呼ぶ。

本記事では広く使われているJWSのみを説明しようと思う。

JWSとは?

  • ルール
    ルール自体はJWTのルールと同じ
     

  • 役割

    • Payloadに**署名(Signature)**を付けて、改ざんされていないことを保証する。

      → 改ざん検知

    • 中身は誰でも読める(暗号化はしていない)。

    • いま一般的に使われているJWTはほぼ全部この形
       

  • 使用例

    1.Header

    {
      "alg": "HS256",
      "typ": "JWT"
    }
    
    • alg:署名アルゴリズム(ここではHMAC SHA-256)
    • typ:トークンの種類(JWT)

    2.Payload

    {
      "sub": "1234567890",   // ユーザーID
      "name": "user",
      "role": "admin",
      "iat": 1695187200,     // 発行時刻 (UNIXタイム)
      "exp": 1695190800      // 有効期限
    }
    
    
    • 署名付きだけど暗号化はされない → 誰でもBase64URLデコードすれば中身は見える
    • subexpなどは予約クレーム

    3.Signature

    Header + Payload を秘密鍵で署名したもの。

    (Base64URLエンコードしたHeaderとPayloadを結合して署名)

    SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
    

    4.JWT全体

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
    eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNjk1MTg3MjAwLCJleHAiOjE2OTUxOTA4MDB9.
    SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
    
    
    • 3つの部分が.で区切られたJWS形式
    • サーバーは Signature を検証して「改ざんされていないか」をチェック
    • Payloadを読み取り、ユーザーIDや権限を判断

5.まとめ

JWTは「自己完結した署名付きデータ」を持ち回ることで、サーバーに状態を持たずに認証・認可ができる仕組み。

署名と暗号化の違い、Payload設計、期限管理などの“ルール”を守ることが安全運用のカギ。

次回は実際に個人開発で詰まったJWT+Cookieの部分を記事にしたいと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?