JWT(Json Web Token)とは
ユーザーがログイン状態を維持するために、サーバーがクライアントに対して発行するトークンを指す。
JWTの基本構造
JWTは、3つの部分から構成され、ドット(.)で区切られた1つの文字列として表現されます。
ヘッダー(Header)
- 使用するアルゴリズム(例:HS256、RS256)とトークンのタイプ(通常は"JWT")を定義
ペイロード(Payload)
- ユーザー情報(例:ユーザーID、権限)や、有効期限などが含まれる
署名(Signature)
- ヘッダーとペイロードを秘密鍵または公開鍵で署名し、改ざんを防ぐ
const jwt = require('jsonwebtoken');
const payload = {
userId: 123,
email: "user@example.com",
role: "user",
exp: Math.floor(Date.now() / 1000) + 60 * 60 // 1時間有効
};
// 下記はペイロード、秘密鍵、ヘッダーを元にJWTを作成
const token = jwt.sign(payload, "SECRET_KEY", { algorithm: "HS256" });
//
// token(ヘッダー.ペイロード.署名 がエンコードされた形で1つの文字列になっている)
// => eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
秘密鍵に関してセキュリティ上の観点で、ベタ書きせずに.envなどに記述し、その値を読み込むのが一般的。
JWT発行までの大まかな流れ
1.ログイン画面にて、ユーザーがメールアドレスとパスワードを入力
2.ログインボタン押下
3.バックエンドで認証処理
4.認証OKでログインが成功したら、JWTを発行
5.発行した、JWTをクライアントに返却
6.クライアントはJWTをCookieに保管
→以降のAPIリクエスト時に、JWTをヘッダーに含めることで、 サーバーはJWTを検証し、認証済みのリクエストかどうかを判断する。
具体的な検証手順
1.ヘッダーのJWTを「.」で分割してデコードし、ヘッダー、ペイロード、署名を取得
2. 1.のヘッダー、ペイロード、秘密鍵で、署名を作成
3. 1.で取得した署名と一致するか検証
実装上の注意点
- JWTの有効期限を設定する
- 永久にログイン状態が維持されないように、サービスの特性を考えて設定
- JWTをLocal Storageに保管しない
- XSS攻撃のリスク
- データがブラウザが閉じられても消えない