JWT: JSON Web Token とは何か、構造と使用方法

著者: IT Sectr 公開日: 2026-04-05 読了時間: 9 分

JWT (JSON Web Token) は、デジタル署名で保護されたJSONオブジェクトとしてデータをやり取りするためのコンパクトな形式です。トークンはHMAC(対称鍵)またはRSA/ECDSA(非対称ペア)を使用して署名でき、データの整合性と信頼性を保証します。IETF RFC 7519(2015年)によると、JWTは認証、安全なクレーム交換、OpenID ConnectのID Token形式として何百万ものアプリケーションで使用されています。

重要なポイント

  • JWT は自己完結型トークンであり、検証に必要なすべてのデータを内部に含んでいます
  • 構造 — ヘッダー、ペイロード、署名の3つの部分をドットで区切ります
  • 署名 — トークン作成後にデータが改ざんされていないことを保証します
  • ステートレス — サーバーはセッションを保存する必要がなく、スケーリングが容易になります
  • セキュリティ — JWTはデータを暗号化せず、署名のみを行います。機密情報はペイロードに含めるべきではありません

JWTとは?

JSON Web Token (JWT) は、JSONオブジェクトとして情報をやり取りするためのコンパクトで自己完結型の方法を定義するオープンスタンダード(RFC 7519)です。JWT内の情報はクレームと呼ばれ、主体(ユーザー)と追加属性に関する表明です。各クレームはキーと値のペアです:ユーザー識別子、ロール、有効期限、発行者。

JWTが自己完結型と呼ばれるのは、検証に必要なすべての情報がトークン自体の中にあるからです。サーバーはトークンの有効性を確認するためにデータベースや外部ストレージにアクセスする必要はなく、署名を確認するだけで済みます。この特性により、JWTは分散システムやマイクロサービスアーキテクチャに最適です。複数のサービスが共有セッションストアなしでリクエストを認証する必要がある場合に特に有効です。

Auth0(2025年)によると、65%以上のモバイルおよびWebアプリケーションがAPI認証の主要トークン形式としてJWTを使用しており、不透明トークンやセッション識別子を上回っています。

JWTの構造:ヘッダー、ペイロード、署名

JWT は、ドットで区切られた3つの部分で構成されます:header.payload.signature。各部分はBase64urlエンコードされたJSONです。各部分を詳しく見ていきましょう。

ヘッダー — アルゴリズムとトークンタイプ

ヘッダーには2つの必須フィールドが含まれます:alg(アルゴリズム — 署名アルゴリズム)とtyp(タイプ — トークンタイプ、常に“JWT”)。アルゴリズムは対称(HS256 — SHA-256を使用したHMAC)または非対称(RS256 — SHA-256を使用したRSA、ES256 — P-256を使用したECDSA)です。非対称アルゴリズムは、クライアントが秘密鍵を保持せずに署名を検証できるため推奨されます。

デコードされたヘッダーの例:

json
{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "key-id-1"
}

ペイロード — クレームとデータ

ペイロードにはクレーム — 主体に関する表明が含まれます。クレームは3つのタイプに分類されます:登録済み(iss、sub、aud、exp、nbf、iat、jti)、公開(開発者がIANAレジストリで定義)、およびプライベート(当事者間で合意)。sub(サブジェクト)は一意のユーザー識別子です。exp(有効期限)はトークンの有効期限タイムスタンプです。iss(発行者)はトークンの発行者です。

json
{
  "sub": "user-abc-123",
  "iss": "https://auth.example.com",
  "aud": "my-mobile-app",
  "exp": 1812345678,
  "iat": 1812342078,
  "role": "premium_user"
}

署名 — 整合性の検証

署名は、秘密鍵またはプライベートキーを使用してヘッダーとペイロードの連結に署名アルゴリズムを適用することで作成されます。式は、HMACの場合はHMACSHA256(base64UrlEncode(header) + “.” + base64UrlEncode(payload), secret)、非対称アルゴリズムの場合はRSASHA256(...)です。受信者は同じ方法で署名を計算し、受信した署名と比較します — 一致すればデータは改ざんされていません。

JWTの仕組み:作成と検証

JWTのワークフローは2つのフェーズで構成されます:認証サーバーによるトークンの作成(発行)と、クライアントまたはリソースサーバーによるトークンの検証です。認証サーバーはユーザーの資格情報を受け取り、クレームを含むペイロードを作成して署名します。結果のJWTは、ログインリクエストへの応答として、またはOAuth 2.0 / OpenID Connectの応答本文でクライアントに送信されます。

モバイル認証におけるJWT

モバイルアプリケーションでは、JWTは次のように使用されます:ログイン成功後、ユーザーはJWT形式のアクセストークンを受け取ります。アプリケーションはそれを安全なストレージ(iOSのKeychain、AndroidのEncryptedSharedPreferences)に保存します。APIリクエストのたびに、アプリケーションはAuthorization: Bearer <token>ヘッダーを追加します。APIサーバーはJWTの署名を検証し、クレームを抽出して、それに基づいてアクセス判断を行います — データベースに問い合わせることなく。

Google Codelabs(2025年)によると、Firebase AuthenticationでのJWT使用は、セッショントークンと比較して認証サーバーへのリクエスト数を40〜60%削減します。これは、各マイクロサービスでデータがローカルに検証されるためです。これは高負荷アーキテクチャで特に重要であり、レイテンシの1ミリ秒ごとがユーザーエクスペリエンスに影響します。毎分50,000リクエストの場合、JWTへの移行により、イントロスペクションリクエストを処理する最大10台のサーバーインスタンスを節約できます。

JWT vs セッショントークン

JWTとセッショントークンは同じ問題 — リクエスト認証 — を解決しますが、アーキテクチャが根本的に異なります。セッショントークンは、サーバーに保存されたセッションデータを参照するランダムな識別子文字列です(ステートフル)。JWTは、すべてのデータを内部に含む自己完結型トークンです(ステートレス)。

パラメータJWTセッショントークン
データストレージトークン内部(自己完結型)サーバー上(セッションストレージ)
スケーリング共有ストレージ不要マルチサーバーにRedis/DBが必要
トークン失効複雑(ブラックリストが必要)簡単(DBからセッションを削除)
サイズ大きい(500〜2000バイト)小さい(16〜64バイト)
署名検証暗号化方式なし(文字列比較)

JWTの利点と欠点

JWTは分散システムで優れています:マイクロサービスは共有ストアなしでローカルにトークンを検証できます。例えば、5つのマイクロサービスからなるアーキテクチャでは、各サービスがネットワークコールなしで1〜2ミリ秒でJWTを検証します。一方、セッショントークンはリクエストごとに中央のRedisへの問い合わせが必要で、10〜30ミリ秒のレイテンシが追加されます。ただし、JWTは失効が困難です — 一度発行されると有効期限まで有効です。セッショントークンはDBやRedisからレコードを削除することで簡単に失効できます。

モバイルアプリケーションの場合、短い有効期間(15〜30分)のJWTとリフレッシュトークンを組み合わせたアプローチが、パフォーマンスとセキュリティのバランスを提供します。JWTはAPIアクセスに使用され、リフレッシュトークン(通常は不透明)は新しいJWTを取得するために使用されます。JWTが侵害された場合、攻撃者は15〜30分間アクセスできます。リフレッシュトークンが侵害された場合、ローテーションと再利用検出によってセッションがブロックされます。

JWTのセキュリティ

JWTのセキュリティは、適切な実装に依存します。最も一般的な脆弱性は“alg none”攻撃です:攻撃者がトークンのヘッダーを“alg”: “none”に変更し、サーバーがアルゴリズムを検証せずに偽造トークンを受け入れてしまいます。防御:ヘッダーのアルゴリズムが期待値(RS256、ES256)と一致することを常に確認し、alg: noneのトークンを拒否します。

一般的な脆弱性

JWTの脆弱性には他にも以下が含まれます:HMACの弱い秘密鍵(数分でブルートフォース)、プライベートキーの漏洩(サーバーに代わって任意のデータに署名)、ペイロードへの機密データの保存(JWTは暗号化せず署名のみ)、JWKヘッダーインジェクション攻撃(カスタム公開鍵の注入)。信頼できるライブラリ — Nimbus JOSE + JWTjjwt(io.jsonwebtoken)PyJWT — を使用することで、これらの脆弱性の悪用リスクを低減できます。

追加のセキュリティ対策としてJWK Thumbprint(RFC 7638)があります:ヘッダー内の拇印(thumbprint)を介して公開鍵をトークンにバインドします。サーバーが各クライアントの期待される拇印を保存している場合、JWKヘッダーインジェクションは不可能になります — サーバーは登録されたものと一致しない鍵をすべて拒否します。OAuth Security Workshop 2025は、金融および医療アプリケーションで使用されるすべてのJWTにJWK Thumbprintを必須の保護として推奨しています。

コード例:KotlinでJWTを扱う

jjwtライブラリ(auth0/java-jwt)を使用すると、Androidアプリケーションで数行のコードでJWTを作成および検証できます。以下の例では、サーバーがsubとroleを含むトークンを生成し、クライアントが署名を検証します。サーバー上の秘密鍵を安全に保存するには、環境変数またはHSM(ハードウェアセキュリティモジュール)を使用してください — コードや設定ファイルに鍵を保存することは重大なセキュリティエラーです。

JWTの生成

kotlin
val secret = "my-256-bit-secret-key-here"
val token = JWT.create()
    .withSubject("user-abc-123")
    .withIssuer("auth.example.com")
    .withClaim("role", "premium_user")
    .withExpiresAt(Date(System.currentTimeMillis() + 3600000))
    .sign(Algorithm.HMAC256(secret))

// クライアントへのトークン送信
println("JWT: $token")

JWTの検証

kotlin
fun verifyToken(token: String): Boolean {
    return try {
        val decoded = JWT.require(Algorithm.HMAC256(secret))
            .withIssuer("auth.example.com")
            .build()
            .verify(token)
        // 署名は有効、クレームを抽出しました
        println("Subject: ${decoded.subject}")
        true
    } catch (e: Exception) {
        println("トークンが無効です: ${e.message}")
        false
    }
}

よくある質問

JWTにパスワードを保存できますか?

いいえ。JWTは署名され、暗号化はされません — 誰でもBase64ペイロードをデコードしてデータを読むことができます。機密情報(パスワード、カード番号、個人データ)は、JWE(JSON Web Encryption)を使用して暗号化された形式でのみ送信する必要があります。

最も安全なJWT署名アルゴリズムはどれですか?

ES256(P-256を使用したECDSA)が推奨されます — はるかに小さい署名サイズでRSA 2048ビットと同等のセキュリティレベルを提供します。RS256はレガシーシステムとの互換性に適しています。HS256(HMAC)は秘密鍵の安全な交換が必要であり、分散アーキテクチャではより困難です。

有効期限前にJWTを失効させるには?

JWTを直接失効させることはできません — expまで有効です。解決策:短い有効期間(15〜30分)を使用する、サーバーで失効したjti(JWT ID)のブラックリストを管理する、またはトークンを秘密鍵のバージョンにバインドします。リフレッシュトークンは標準的な方法 — ストレージから削除 — で失効させます。

JWTとBearerトークンの違いは?

Bearerトークンは概念です:保有者がアクセスに使用できる任意のトークン。JWTは特定のトークン形式です。BearerトークンはJWTでも不透明な文字列でも構いません。JWTはBearerの概念に自己完結性と暗号化検証を追加します。

JWTの標準的なサイズは?

RS256署名の一般的なJWTは500〜2000バイトです。ペイロードに多くのカスタムクレームが含まれているか、大きな鍵を使用した非対称署名が使用されている場合、サイズは4〜5KBに達する可能性があります。これはセッショントークン(16〜64バイト)よりも大幅に大きく、HTTPヘッダーサイズに影響を与えます。

まとめ

  • JWT — デジタル署名付きのコンパクトな自己完結型JSONトークン
  • 構造 — 3つの部分:ヘッダー(アルゴリズム)、ペイロード(クレーム)、署名(署名)
  • ステートレス — サーバーはデータベースに問い合わせずにトークンを検証
  • JWT vs セッション — JWTはスケーリングに優れ、セッションは失効に優れる
  • セキュリティ — alg none、弱い鍵、JWKインジェクションからの保護が必須
  • ペイロードは暗号化されていない — 機密データにはJWEが必要
  • JWT — OpenID ConnectのID TokenとFirebase Authenticationトークンの標準形式

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください