JWTについて

# 目次

1. JWTの概要
1. JWTの何が嬉しいか？
1. どんな時に使う？
1. JWTの構造
1. まとめ

## そもそものトークンについて

* Web開発において「Webトークン」は、ほとんどの場合JSON Webトークンを指します。
* 認証で用いる際の一意の情報となる。
* ユーザーがログアウトしたり、アプリを終了したりすると認証トークンは無効になる。
* 用途としては、認証時。パスワードのみの認証ではセキュリティ的に不十分。
トークンによる認証でより安全に。

# 1. JWTの概要

![JSON Web Tokens are an open, industry standard R  7519 method for representing.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/de67fb5f-607b-b8d6-fe4c-02c2a3b418b4.png)

> JSON Web Token (JWT) はオープン スタンダード ( RFC 7519 ) であり、関係者間で JSON オブジェクトとして情報を安全に送信するためのコンパクトで自己完結型の方法を定義します。

Json Web Tokenの略。ジョットとも言います。

### つまり？

・ヘッダ​
・ペイロード​
・著名​
のブロックから出来ていて、Base64でエンコードしてそれらを.(ドット)でつないだもの​

（後で構造については詳しく説明）

* 実際のデータはJson文字列
* Jsonを用いた電子署名によって、データが改ざんされていないことを証明する
* URLセーフ（URLとして機能するため、Webと相性が良い）

→ そのためwebサービスで使用される

## JWTの何が嬉しい？

### JSON は XML よりも冗長ではないため、エンコードされるとサイズも小さい
JWTを構成する際にBase64でエンコードする必要がある​

（なぜエンコードサイズがXMLよりも小さいか？）
タグの長さに違いがある
> XMLのタグは最低でも3bite（閉じタグは最低4bite）あります。運用面を考えれば要素名を1bite文字1文字に統一することは難しいでしょう。ということで、実際にはもっと増えることになります。
その点、JSONのタグは「[]{}:”」のどれか1文字1biteと、非常にシンプルです。
その為、構文解析の処理がXMLよりも速くなります。
https://www.w2solution.co.jp/tech/2022/02/25/xml-vs-json/

### [JWT は SAML（シングルサインオン時に使われる） よりもコンパクトになる]​
シングルサインオン・・・1度のユーザー認証によって複数のシステム利用可能にする仕組み。
SAML・・・認証を行うためのプロトコル
これによって、JWT は HTML および HTTP 環境で渡されるのに適した選択肢になっています​

Base64・・・データを64種類の印字可能な英数字のみを用いて、それ以外の文字を扱うことの出来ない通信環境にてマルチバイト文字やバイナリデータを扱うためのエンコード方式である

## どんな時に使う？用途
* 認証用のトークン
    * 各リクエストにトークンを含んで認証する（シングルサインオンの仕組みにも使われる）

* 情報伝達
    * 公開鍵と秘密鍵のペアを使用して署名できるため、送信者が本人であることを確認できる

* OAuth2
    * Facebook連携 / Google連携 の仕組み
    * データベースで管理する必要がなくなる
    * ただし有効期限だけを延ばすと言った操作はできないのでリフレッシュトークンを使ってトークン自体改める必要がある

![スクリーンショット 2022-10-12 16.22.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/77e17020-a5b4-8eba-5a0c-96f966743576.png)

* OpenID Connect
    * OAuth2をベースにした認証

![スクリーンショット 2022-10-12 16.26.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/1ce6621b-c171-ecd9-d6e6-84b585bcdc6d.png)

認証・・・本人確認
認可・・・アクセス許可（システムへのアクセスを許可する）

* メールアドレス確認

メールアドレスと有効期限でJWTを生成し、それをメールアドレス認証用のURLとすればデータベースで確認コードを保存することなく、正しいメールアドレスであるという検証ができます。

改ざんはできないので別のメールアドレスを適用することはできませんし、自分のメールアドレスであればURLに含まれていても問題はないです。あと、JWTはURLセーフになっていますので、URL中に含めるのも問題ありません。

## JWTの構造

![スクリーンショット 2022-10-15 9.48.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/f24d3edf-cfaf-140c-0f6e-ca358329fdc2.png)


ヘッダ
ペイロード
サイン

例：xxxxx.yyyyy.zzzzz

### ヘッダ

```sample.json
{
  "alg": "HS256",
  "typ": "JWT"
}
```

* 2つの部分で構成
    * alg:使用されている署名アルゴリズム
    * typ:トークンのタイプ (JWT) 
* この部分のjsonはBase64Urlでエンコードされヘッダとして構成される

### ペイロード

```sample.json
{
  "sub": "1234567890", ユーザー識別子（プライマリーキーなどが使用される）
  "name": "John Doe",
  "admin": true
}
```

* ペイロードは、クレーム情報を含んでいる
* クレーム・・・アプリ間のやりとりに必要な属性情報
* クレームも3種類に分けられるが細かい説明は省く
* ペイロードもBase64Urlエンコードされて、JSON Web トークンの 2 番目の部分を形成します
* ※ 改ざんからは保護されているが誰でもみることが出来る点に注意。暗号化されていない限り、JWT のペイロードまたはヘッダー要素に秘密情報を入れないようにする必要がある

### サイン

```
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)
```
（HMAC SHA256 アルゴリズムの例）

* エンコードされたヘッダー、エンコードされたペイロード、シークレットヘッダーで指定されたアルゴリズム（`"alg": "HS256"`）で署名する部分
* メッセージが途中で変更されていないことを確認するために使用する
* Base64urlエンコードする

# まとめ

* Json Web Tokenの略。ジョット
* Webの認証によく使用される
* ヘッダ​,ペイロード​,著名​のブロックから出来ていて、Base64でエンコードしてそれらを.(ドット)でつないだもの
* 認証用のトークン、OAuth2,OpenIDConnect などで認証を行う際に使用される

# 参考
https://jwt.io/introduction

https://qiita.com/knaot0/items/8427918564400968bd2b