開発者:ナレッジ:JWTについて
本システムでは、認証にJWT(JSON Web Token)を使用しています。
JWTとは
JWTは、簡単に言えばユーザの認証情報をJSON形式でエンコードし、署名を付与したものです。この署名により、そのJSONの改ざんが難しくなるため、認証情報を比較的安全に扱うことができます。
JWTの構造
JWTはこのような文字列です。
注目してほしいのが、.で区切られた3つの部分です。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvbiBEb2UiLCJpYXQiOjE1MTYyMzkwMjJ9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
途中のピリオドに着目し、これを3つへと分解してみましょう。
-
ヘッダー(Header)
alg:アルゴリズム(今回はHS256、HMAC SHA-256)typ:トークンの種類(今回はJWT)- この部分はBase64エンコードされています。
-
ペイロード(Payload)
sub:ユーザIDname:ユーザ名iat:トークンの発行日時(UNIXタイムスタンプ)- この部分もBase64エンコードされています。
-
署名(Signature)
- ヘッダーとペイロードを結合し、秘密鍵を使ってハッシュ化したものです。
- この部分はBase64エンコードされています。
JWTの利点
- 軽量
JWTは、ヘッダーとペイロードをBase64エンコードしたものに署名を付与するだけであるため、軽量です。
また、署名を検証するだけでその情報が正しいことを検証でき、ユーザ情報を取得できるため、サーバ側の負荷(特にRDB負荷)を軽減することができます。 -
ステートレス
JWTは、認証情報をトークンに持たせるため、サーバ側にユーザ情報を保存する必要がありません。そのため、スケーラビリティが高くなります。
事実として、本システムではAPIサーバ部分を任意の台数に増やすことができます。 -
拡張性 JWTはJSON形式で情報を持つため、ユーザ情報以外にも様々な情報を持たせることができます。本システムでは、テナンシー情報、ロール(権限)情報などを持たせています。
セキュリティ面について
JWTには、署名が付与されます。
この署名によって、ユーザはトークンを改ざんすることが難しくなります。(ペイロードや署名を書き換えると、署名が合わなくなるため気がつくことができます。)
しかしながら、JWTはステートレスな認証方式であるため、トークンが盗まれた場合、そのトークンを使って認証を行うことができてしまいます。(サーバ側のRDBと照合を行わないため)
そのため、本システムでは「Access Token」と「Refresh Token」の2つを使用することで、この弱点を補っています。
トークン周りを操作するときは、こちらを参照してください。