jwtとは
json形式で表現された認証情報などをurl文字列として送受信できるよう、符号化やデジタル署名の仕組みを規定した標準規格。
jwtにデジタル署名の仕組みがあるのではなく、jwsの署名の仕組みを利用し作成された、トークンの構造をjwtと呼ぶ。(jwt認証のところで説明)
※ 補足
符号化 ・・・ エンコードすること
デジタル署名 ・・・ 暗号化を利用して、データの信頼性を保つ仕組み。公開鍵方式や共通鍵方式などを使って、データが改竄されていないことや、作成者の証明を行うこと。
jwtの仕組み
・json形式のデータをURLセーフにする
→ httpヘッダーやクエリパラメータにはスペースや/などの特殊文字を入れることができないため、json形式のデータをbase64URLエンコードし、httpヘッダーやクエリパラメータに埋め込めるようにする。
・jsonをコンパクトにする
→ よく使われるjsonのキー名を省略形にすることで、データをコンパクトにする。このようなjwtのjsonをクレームと言う。
省略形の例は以下画像
※ 上記は主な登録クレーム(jwtのjsonの項目)であるが、全て必須ではない。また、登録クレーム以外にも任意のクレームを追加することも可能。(例えばメールアドレスをクレームとして追加するなど。)
jwt認証とは
-
jwtのトークン構造について
ヘッダ、ペイロード、シグネチャの3つからなる。上記のjwtの仕組みで説明したjsonはペイロードにあたる。ヘッダーには何が含まれているかというと、署名のアルゴリズムとトークンの種別が含まれる。シグネチャはヘッダとペイロードを暗号化したものとなる。
ヘッダ、ペイロード、シグネチャをそれぞれbase64URLエンコードし、ヘッダ.ペイロード.シグネチャという形でドットで繋いだものが、jwt形式のトークンとなる。 -
jwsについて
jwt自体はhttpヘッダーやクエリパラメータによるデータの送受信のためにjsonを都合いいように加工する仕組みであり、認証とは全く関係ない。つまり、base64URLデコードすれば、誰でも内容の閲覧や改竄できてしまうセキュリティガバガバな仕組みである。
上記を解決するための仕組みとしてjws(json web signature)がある。具体的には、 公開鍵方式などを用いて、ヘッダとペイロードを暗号化(署名)し、シグネチャに含めるという仕組みである。(ヘッダ+ペイロード = シグネチャ)
上記を検証するとき、仮にヘッダやペイロードが改竄されていた場合、復号化したシグネチャの内容と、ヘッダとペイロードが異なるため、改竄されたことを検知することができる。 -
jwt認証の仕組み
・iDとパスワードの認証に成功したら、アプリケーション(バックエンド)はjwtトークンを発行し、ユーザー(フロント)に送信。(ここの処理は、IDプロバイダーと呼ばれる外部アプリに委託することがよくあるらしい。)
・受け取ったユーザー(フロント)はjwtトークンをクッキーに保存し、その後のアプリケーション(バックエンド)との通信時にはhttpヘッダーにjwtトークンを含める。
・jwtトークンを受け取ったアプリケーション(バックエンド)は秘密鍵を使用し、シグネチャを復号化。シグネチャとヘッダ+ペイロードを比較し、差異がないかチェック。なければ認証OK。