Web開発でよく見かける JWT(JSON Web Token) というものが何なのか調べたのでまとめます。
JWTとは
JWT とは、JSON Web Token の略称であり、属性情報 (Claim) をJSONデータ構造で表現したトークンの仕様です。RFC 7519 で標準化された仕様であり、広く利用されています。
JWTは、次のような特徴を持っています。
- 署名 されているため改ざんをチェックできる
- URL Safe (URLに含むことができる文字のみで構成される)
- 実際のデータは JSON 文字列
簡単に言うと、改ざんできないURLに埋め込めるJSON文字列のことです。
1 にある通り署名されているため、改ざんされているかどうかがチェックできるのですが、デコードしてJSON文字列を得ることは、鍵情報を知らなくてもだれでもできるということは覚えておきましょう。署名を除くと、ただの Base64 でエンコードされた文字列です。
JWTの仕組み
JWTは、以下の3つのパーツで構成されます。
- ヘッダー(Base64文字列)
- クレーム情報、つまりデータ本体(Base64文字列)
- 署名(バイナリ文字列)
3つのパーツが . (ピリオド) で区切られた文字列がJWTです。例えば次のような文字列がJWTです。
赤がヘッダー部分、ピンクがクレーム部分、水色が検証に使われる署名部分です。
ヘッダーとクレームはそれぞれJSON文字列がBase64でエンコードされただけの文字列なので、デコードすることでJSONを取得できます。
ヘッダーとクレームの中身のJSONデータはこうなっています。
ヘッダー
{
"alg": "RS256",
"typ": "JWT"
}
クレーム
{
"username": "山田",
"exp": "2019/04/01"
}
例えばこのデータを受け取ると、ユーザー(“山田”)が “2019/04/01” までの認証を受けていることがわかるといった感じです。
ヘッダーデータ
ヘッダーデータはメタ情報を含めます。
alg には署名に使われているアルゴリズムを指定します。これは必須です。
typ はトークンタイプを表します。”JWT”が推奨されますが、これは任意です。
クレームデータ
クレームデータについては、予約済のクレーム名が存在しています。これらについては必須項目ではありませんが、すでに役割が定義されています。
これはクレームが相互運用性を持つように期待されているためです。独自に実装する場合は予約語に注意が必要です。
予約語データをコンパクトにするために略語で定義されています。それぞれの意味と役割をいかにまとめます。
予約語一覧
予約語 | 意味 | 役割 |
---|---|---|
iss | Issuer | JWT発行者(サーバー側)の識別子 |
sub | Subject | JWTの主語となる主体の識別子 |
aud | Audience | JWT を利用する主体(クライアント側)の識別子 |
exp | Expiration Time | 有効期間終了日時。これ以降にこのJWTを処理してはいけない。 |
nbf | Not Before | 有効期間開始日時。これ以前にこのJWTを処理してはいけない。 |
iat | Issued At | JWTの発行日時 |
jti | JWT ID | JWTのための一意な識別子。重複が起きないように割り当てる必要がある。 |
typ | Type | コンテンツタイプの宣言 |
署名
署名部分は検証時に使われます。データが改ざんされているかどうかをチェックするために署名が使われますが、それ以外ではあまり意識することはありません。
JWTが利用される場面
主に認証の場面に使われます。
何かしらのサービスにログインした場合、その認証情報を保持しておきますが、その際の有効期限やユーザー名などを JWT として保持しておくといった感じです。
FirebaseやAWSなどでもJWTで作られたトークンを用いて認証情報を保持しています。もちろんWTでトークンを発行することで、独自の認証機能を作ることも可能です。
JWTの使い方とライブラリ
JWTを使う場合、ライブラリを使用することになると思います。さまざまな言語環境でライブラリが存在しているのでそれを使います。
上記ページの下の方(Libraries for Token Signing/Verification)に JWT の各ライブラリが載っています。それぞれで予約語や署名アルゴリズムについての検証結果もあるので、適当なライブラリを選んで使うとよいでしょう。
JWTのデバッガー
JWTをデバッグするのにも上記ページが便利です。JWTの仕組みがよくわかりました。
以上。
コメントを書く