JSON Web Token

Web Token(JWT)は、データに署名や暗号化を施すための標準規格(RFC 7519)です。JWTは、トークン内に任意の情報(クレーム)を保持でき、例えばサーバーがクライアントに対して「管理者としてログイン済」という情報を含むトークンを生成できます。クライアントはそのトークンを、自身が管理者としてログイン済であることの証明に使用できます。

JWTの構造

JWTのトークンは、以下の3つの要素から構成されます。

1. ヘッダー: トークンの種類や署名アルゴリズムなどの情報を含む形式のデータです。
2. ペイロード: 実際に伝えたい情報(クレーム)を含む形式のデータです。例えば、ユーザーID、有効期限、権限などの情報が含まれます。
3. 署名: ヘッダーとペイロードを特定のアルゴリズムでハッシュ化し、秘密鍵で暗号化して生成されます。この署名により、トークンの改ざんを検知できます。

これらの3つの要素は、Base64urlエンコードされた上で、ピリオド(.)で連結されます。

例:

ヘッダー: {"alg":"HS256","typ":"JWT"}
ペイロード: {"loggedInAs":"admin","iat":1422779638}
署名: gzSraSYS8EXBxLN_oWnFSRgCzcmJmMjLiuyu5CSpyHI


上記の例では、秘密鍵が`secretkey`の場合、最終的なトークンは以下のようになります。

`eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dnZWRJbkFzIjoiYWRtaW4iLCJpYXQiOjE0MjI3Nzk2Mzh9.gzSraSYS8EXBxLN_oWnFSRgCzcmJmMjLiuyu5CSpyHI`

生成されたトークンは、HTMLとHTTPの仕組みの中で簡単に扱うことができ、ウェブブラウザでの利用に適しています。

JWTの使用方法

ユーザーがサーバーにログインする際、従来のセッション認証ではCookieにセッションIDが格納されていましたが、JWTではトークンが返され、ローカルストレージなどに保存して利用します。認証が必要な機能やリソースへのアクセス時には、クライアントはAuthorizationヘッダーにBearerスキーマを用いてトークンをサーバーに送信します。例を挙げると、Authorizationヘッダーは以下のようになります。

`Authorization: Bearer eyJhbGci...(中略)...yu5CSpyHI`

JWTは、サーバー側で認証状態を保持しないステートレスな認証方式です。サーバーは、Authorizationヘッダーで渡されたトークンが正しい署名を持っているかを検証し、アクセスを許可します。JWTには認証に必要な情報が全て含まれているため、データベースへの問い合わせを減らすことができます。

JWTの標準フィールド

ペイロードには、RFCで定義された以下の標準フィールド(クレーム)を含めることができます。

`iss` (Issuer): トークンを発行した主体。
`sub` (Subject): トークンの主題。ユーザーIDなど。
`aud` (Audience): トークンを使用する対象。
`exp` (Expiration Time): トークンの有効期限。
`nbf` (Not Before): トークンが有効になる日時。
`iat` (Issued At): トークンが発行された日時。
`jti` (JWT ID): トークンの一意な識別子。

ヘッダーには、以下のフィールドが使用可能です。

`alg` (Algorithm): 署名アルゴリズム。
`typ` (Type): トークンの種類(通常はJWT)。

脆弱性と批判

JWTはステートレスであるため、一度発行されたトークンを無効にすることが難しいという欠点があります。従来のセッションのようにサーバー側で状態を管理すれば無効化は可能ですが、その場合、ステートレスであるメリットが失われます。

また、JWTライブラリの一部には、`alg`クレームに署名なし(`none`)を指定した不正なトークンを処理してしまう脆弱性が報告されています。これらの脆弱性は修正されていますが、`alg`クレーム自体を廃止すべきという意見もあります。署名アルゴリズムの脆弱性に対する対策として、以下の点が挙げられます。

JWTヘッダーのみを見て検証しない。
利用するアルゴリズムを理解する。
適切なキーサイズを使用する。

JWTは、ウェブアプリケーションの認証において重要な役割を果たしており、その特性を理解した上で適切に利用することが求められます。

もう一度検索

【記事の利用について】

タイトルと記事文章は、記事のあるページにリンクを張っていただければ、無料で利用できます。
※画像は、利用できませんのでご注意ください。

【リンクついて】

リンクフリーです。