先日、「世界最悪のログイン処理コード」を解説してみた という記事を読んだのですが、そこに次のようなことが書いてありました。
ちなみに真っ当なログイン処理の場合、書き込む情報をランダムなログインIDにしたりJSON Web Token(JWT)にしたりします。
自分もちょうどログイン処理を作成していて、JWTは初見だったので調べたことを備忘録としてまとめておきます。
JWT とは
JavaScript Object Notation Web Token ⇒ JSON Web Token ⇒ JWT で「ジョット」と読む。
IT用語辞典には、以下のようにまとめられている。
JWT(JSON Web Token)とは、JSON形式で表現された認証情報などをURL文字列などとして安全に送受信できるよう、符号化やデジタル署名の仕組みを規定した標準規格。IETFによってRFC 7519として標準化されている。
JWT の構造
構造についてIT用語辞典では、次のように説明されています。
ヘッダー(header)、ペイロード(payload)、署名(signature)の3つの部分に分かれており、これらをそれぞれBase64URL(Base64をURLパラメータ仕様に適合させたもの)方式で符号化して「.」(ピリオド)で連結したものがトークンとなる。
そこで、JWTのデバッグができるサイト (jwt.io) で作成したデータを基に、その構造を見てみます。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
たしかに、3つの文がピリオド「.」で結合された構造になっています。3つの文章は上から順に「ヘッダー」、「ペイロード」、「署名」となっています。
ヘッダー部分
ヘッダーは、署名のハッシュ値を計算するアルゴリズム alg
とトークンタイプ typ
を設定します。
{
"alg": "HS256",
"typ": "JWT"
}
上記の場合は、ハッシュ値計算にHMAC SHA-256を使用、トークンタイプはJWTに設定されている。
ハッシュ値計算は、HS256以外にもHS512, RS256などが使用できる。
ペイロード部分
やり取りするデータ本体を入れる場所。クレームデータとも呼ばれ、規格上で意味が定められている「登録済みクレーム」以外に自分で任意のプロパティを含ませることもできる。
{
"sub": "1234567890",
"name": "John Doe",
"admin": true,
"iat": 1516239022
}
name, admin は自分で追加したプロパティ。
登録済みクレームの名前と意味は以下の通りです (詳細はこちら) 。
クレーム | 概要 | 型 | |
---|---|---|---|
iss | Issuer | JWT発行者の識別子 | String or URI |
sub | SubJect | 主体に関する記述 | String or URI |
aud | Audience | JWT受信者の識別子 | String or URI |
exp | Expiration Time | トークンの有効期限 | 1970-01-01 00:00:00Zからの秒数を数値(IntDate)で指定 |
nbf | Not Before | このプロパティで設定した日時以降にJWT処理が可能になる | 1970-01-01 00:00:00Zからの秒数を数値(IntDate)で指定 |
iat | Issued At | JWT発行日時。 | 1970-01-01 00:00:00Zからの秒数を数値(IntDate)で指定 |
jti | JWT ID | JWTのための一意(ユニーク)な識別子。重複が起きないように割り当てる必要がある。 | 大文字と小文字を区別する文字列 |
署名
data = Base64URLEncode( header ) + ‘.’ + Base64URLEncode( payload )
signature = Hash( data, secret )
Base64URLEncode( header ) は、ヘッダー部分をBase64URLを使って変換した文字列
Base64URLEncode( payload ) は、ペイロード部分をBase64URLを使って変換した文字列
補足: Base64 エンコードとBase64URLエンコード
Base64URLエンコードについてはこちらの記事が詳細に説明してくださっていました。
Base64 は、データを 64 種類の印字可能な英数字のみを用いて、それ以外の文字を扱うことの出来ない通信環境にてマルチバイト文字やバイナリデータを扱うためのエンコード方式。
Base64URLエンコードとは
URL に使用できる Base64 Encode のことを指します。
まず、Base64 Encoding をしたあと、に各記号を置き換えるようです。
+
を-
に置換/
を_
に置換