awesome-hacks
Docs

JWTの基礎

JWTが何のためのトークンなのか、Bearer認証でどう使われるのかをAPI実装前に理解する

最終更新:2026/05/13

JWTとは

JWT(JSON Web Token)は、ログイン後のユーザー情報や権限などを 署名付きの文字列 として表現するための仕様。

NestJSやNext.js固有のものではなく、Web API全般で使われる認証・認可まわりの仕組み。

よくある使い方は次の流れ。

1. ユーザーがメールアドレスとパスワードでログインする
2. サーバーが認証に成功したらJWTを発行する
3. クライアントは以後のAPIリクエストにJWTを付けて送る
4. サーバーはJWTを検証し、誰のリクエストか判断する

APIではどう送るか

REST APIでは、HTTPヘッダーの Authorization に入れて送ることが多い。

GET /users/me
Authorization: Bearer xxxxx.yyyyy.zzzzz

この Bearer は「このトークンを持っている人として扱ってください」という意味合い。
JWT認証の記事で出てくる Authorization: Bearer <accessToken> はこの形。

JWTの中身

JWTは、見た目としてはドット区切りの3パートになっている。

header.payload.signature
  • header … 署名アルゴリズムなどの情報
  • payload … ユーザーIDやメールアドレスなど、アプリ側が使いたい情報
  • signature … 改ざんされていないことを確認するための署名

たとえばpayloadには次のような情報を入れることがある。

{
  "sub": "user_id_123",
  "email": "taro@example.com",
  "iat": 1710000000,
  "exp": 1710003600
}

sub はsubjectの略で「このトークンの主体」を表す。ユーザー認証ではユーザーIDを入れることが多い。
exp は有効期限。期限切れのJWTは拒否する。

署名は「暗号化」ではない

ここは重要。

JWTは署名されているが、基本的には 暗号化されているわけではない
JWTのpayloadは、ツールを使えば中身を読める。

つまり、payloadには次のような情報を入れない。

  • パスワード
  • クレジットカード番号
  • 個人情報の詳細
  • 外部に漏れると困る秘密情報

JWTに入れるのは、最低限の識別情報に留めるのが基本。

サーバーは何を検証するか

JWTを受け取ったサーバーは、主に次を確認する。

  • 署名が正しいか
  • 有効期限が切れていないか
  • payloadの中身がアプリの想定どおりか

署名検証には JWT_SECRET のような秘密鍵を使う。
この秘密鍵が漏れると、不正なJWTを作られる危険があるため、コードに直書きせず .env などで管理する。

セッション認証との違い(ざっくり)

従来のセッション認証では、サーバー側にセッション情報を保存し、ブラウザにはセッションIDを持たせることが多い。

JWT認証では、クライアントがJWTを持ち、サーバーはリクエストごとにJWTを検証する。
そのため、サーバー側にセッション保存を持たずに済む構成を作りやすい。

ただし、JWTには注意点もある。

  • 盗まれると有効期限まで使われる可能性がある
  • 一度発行したトークンを途中で無効化する設計は少し難しい
  • 保存場所(localStorage / Cookieなど)にはセキュリティ上の判断が必要

参考:NestJSでの使用例

NestJS Guard / JWT認証では、次の用途でJWTを使う。

POST /auth/login
↓
メールアドレスとパスワードを検証
↓
JWTを発行
↓
GET /users/me に Authorization: Bearer <JWT> を付けてアクセス

NestJS側では、JwtStrategy がJWTを検証し、JwtAuthGuard が「このAPIに入ってよいか」を判定する。

参考