コンテンツにスキップ

開発者:ナレッジ:JWTについて

本システムでは、認証にJWT(JSON Web Token)を使用しています。

JWTとは

JWTは、簡単に言えばユーザの認証情報をJSON形式でエンコードし、署名を付与したものです。この署名により、そのJSONの改ざんが難しくなるため、認証情報を比較的安全に扱うことができます。

JWTの構造

JWTはこのような文字列です。
注目してほしいのが、.で区切られた3つの部分です。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvbiBEb2UiLCJpYXQiOjE1MTYyMzkwMjJ9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

途中のピリオドに着目し、これを3つへと分解してみましょう。

  1. ヘッダー(Header)

    {
        "alg": "HS256",
        "typ": "JWT"
    }
    

    • alg:アルゴリズム(今回はHS256、HMAC SHA-256)
    • typ:トークンの種類(今回はJWT
    • この部分はBase64エンコードされています。
  2. ペイロード(Payload)

    {
        "sub": "1234567890",
        "name": "John Doe",
        "iat": 1516239022
    }
    

    • sub:ユーザID
    • name:ユーザ名
    • iat:トークンの発行日時(UNIXタイムスタンプ)
    • この部分もBase64エンコードされています。
  3. 署名(Signature)

    • ヘッダーとペイロードを結合し、秘密鍵を使ってハッシュ化したものです。
    • この部分はBase64エンコードされています。

JWTの利点

  • 軽量
    JWTは、ヘッダーとペイロードをBase64エンコードしたものに署名を付与するだけであるため、軽量です。
    また、署名を検証するだけでその情報が正しいことを検証でき、ユーザ情報を取得できるため、サーバ側の負荷(特にRDB負荷)を軽減することができます。
  • ステートレス
    JWTは、認証情報をトークンに持たせるため、サーバ側にユーザ情報を保存する必要がありません。そのため、スケーラビリティが高くなります。
    事実として、本システムではAPIサーバ部分を任意の台数に増やすことができます。

  • 拡張性 JWTはJSON形式で情報を持つため、ユーザ情報以外にも様々な情報を持たせることができます。本システムでは、テナンシー情報、ロール(権限)情報などを持たせています。

セキュリティ面について

JWTには、署名が付与されます。
この署名によって、ユーザはトークンを改ざんすることが難しくなります。(ペイロードや署名を書き換えると、署名が合わなくなるため気がつくことができます。)

しかしながら、JWTはステートレスな認証方式であるため、トークンが盗まれた場合、そのトークンを使って認証を行うことができてしまいます。(サーバ側のRDBと照合を行わないため)

そのため、本システムでは「Access Token」と「Refresh Token」の2つを使用することで、この弱点を補っています。
トークン周りを操作するときは、こちらを参照してください。