JWTとそれを用いた認証について

JWTについて


JSON Web Tokenの略です。RFC7519で標準化されています。読み方はjot(ジョット)です。JWS形式でエンコードされたものかもしくはJWEにのっとって暗号化されたJSONを指す。という認識でよいはず。

OpenIDファウンデーションジャパンが翻訳している日本語版があるので、そちらを見るとだいたいわかるのではないかと[1]思います。他にはAuth0のドキュメントがまとまっていてよいと思います。

JWSについて


前述のとおりJWTを生成するための仕様で、署名してBase64でURLで使用できる文字のみでエンコードしたものという認識でよいと思います。だいたいJWTの話がでたときはJWSのケースが多いように見受けられるので、以降JWS前提で話を進めることにします。

RFC7515で標準化されています。

構造


JWTは下記のの3つからなります。

  • ヘッダー
  • クレーム
  • デジタル署名

これらを.でくっつけたものがJWTです。具体的には下記のようになります。(下記は見やすくするために改行していますが実際は改行されていません)

1
2
3
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

また、上記のJWTはAuth0が運用するjwt.ioのサンプルを引用しています。

ヘッダー

ヘッダーにはアルゴリズムとトークンのタイプが格納されています。JWTの場合はtypは全てJWTになるはずです。たぶん。

1
2
3
4
{
"alg": "HS256",
"typ": "JWT"
}

クレーム

予約済みの項目とカスタムの項目からなります。カスタムの項目は例えばユーザーの項目(名前など)になります

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"sub": "AAAA-VVVV-CCCC",
"event_id": "12345-5678-9000",
"token_use": "access",
"scope": "aws.cognito.signin.user",
"auth_time": 1557655406,
"iss": "https://cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_ABCDEFGHIJK",
"exp": 1557655406,
"iat": 1557651806,
"jti": "0987654",
"client_id": "clientId12345",
"username": "test1"
}

予約済みクレームはこちらで確認できます。

署名

JWTが改ざんされていないかといったことや本人かどうかといった認証に使用します。

JWK


JWKは認証用のサーバから発行されたJWTを検証するための公開鍵情報を含むJSONという認識でたぶん良いです。RFC7517で標準化されています。

JWT認証について


JWT認証はAPIの認証に使用されることが多いと思いますが、これは私の認識が正しければ下記のようなフローになるはずです。

  1. クライアントはログイン(フォームなど)で認証を行う
  2. サーバがJWTを返す。クライアントはなんらかの方法(Cookieなど)でローカルに保存する
  3. クライアントはリクエスト時にヘッダー(Authorization)でJWTをサーバに送る
  4. サーバはクライアントから送信されてきたJWTが正しいか検証する
  5. 検証結果に応じてレスポンスを返す

この時にサーバはクライアントが送信してきたJWTを検証して、問題なければ200系を返すでしょうし、認証に不備があれば401を返すという感じになると思います。

参考


RFC7519
JSON Web Tokens
JSON ウェブトークンの検証
JSON Web Token (JWT)draft-ietf-oauth-json-web-token-11


  1. 全部翻訳されているのかどうかがちょっとわからないですが ↩︎