MeWrite Docs

JWT: Invalid signature

JWTトークンの署名検証に失敗した際のエラー原因と解決策

概要

JWTトークンの署名が秘密鍵と一致しない場合に発生するエラーです。

エラーメッセージ

JsonWebTokenError: invalid signature

原因

  1. 秘密鍵の不一致: 署名時と検証時で異なる鍵
  2. アルゴリズムの不一致: HS256 vs RS256等
  3. トークンの改ざん: ペイロードが変更された
  4. 環境間の鍵の違い: 開発と本番で異なる鍵

解決策

1. 秘密鍵を確認

1
2
3
4
5
// 署名時
const token = jwt.sign(payload, process.env.JWT_SECRET, { algorithm: 'HS256' });

// 検証時(同じ鍵を使用)
const decoded = jwt.verify(token, process.env.JWT_SECRET, { algorithms: ['HS256'] });

2. アルゴリズムを明示

1
2
3
4
5
// 悪い例: アルゴリズム未指定
jwt.verify(token, secret);

// 良い例: アルゴリズムを明示
jwt.verify(token, secret, { algorithms: ['HS256'] });

3. RS256(公開鍵/秘密鍵)の場合

1
2
3
4
5
6
7
// 署名(秘密鍵)
const privateKey = fs.readFileSync('private.pem');
const token = jwt.sign(payload, privateKey, { algorithm: 'RS256' });

// 検証(公開鍵)
const publicKey = fs.readFileSync('public.pem');
const decoded = jwt.verify(token, publicKey, { algorithms: ['RS256'] });

4. 環境変数を統一

1
2
# .env.development と .env.production で同じ値
JWT_SECRET=your-super-secret-key-here

5. デバッグ方法

1
2
3
4
5
# JWTのペイロードを確認(署名検証なし)
echo "eyJhbGciOi..." | cut -d'.' -f2 | base64 -d | jq

# ヘッダーを確認(アルゴリズムの確認)
echo "eyJhbGciOi..." | cut -d'.' -f1 | base64 -d | jq
1
2
3
4
// Node.js でデコードのみ(検証なし)
const decoded = jwt.decode(token, { complete: true });
console.log('Header:', decoded.header);  // { alg: 'HS256', typ: 'JWT' }
console.log('Payload:', decoded.payload);

オンラインツール:

  • jwt.io - JWTのデコードと検証

よくある間違い

  • 秘密鍵をハードコード
  • none アルゴリズムを許可
  • Base64エンコードの有無の不一致

関連エラー

関連エラー

Security の他のエラー

最終更新: 2025-12-10