0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JWT認証とは何か?ログインとの違いを理解する

Posted at

JWT認証とは何か?ログインとの違いを理解する

混乱したきっかけ

@Post('login')  // 認証不要(ログイン用)
login(@Body() loginDto: LoginDto) {
  return this.authService.login(loginDto);
}

@UseGuards(JwtAuthGuard)  // ← このメソッドは認証必要
@Get('profile')
getProfile(@Request() req) {
  return req.user;
}

「ログインは認証不要なのに、プロフィール取得は認証必要?」

Nest.js触りたてで、この疑問がでてきたので、Claude Sonnet4さんにJWT認証の本質と仕組みを聞きました。
(※ そのまま回答を載せています)

JWT認証が解決する問題

従来の課題:「誰がリクエストしているか分からない」

GET /api/profile
# このリクエストは誰から?本当に信頼できる?

Webは基本的にステートレスなので、サーバーはリクエストを送った人が誰なのか分かりません。

JWT認証の解決策:「身分証明書」の仕組み

GET /api/profile
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
# ↑ これが「デジタル身分証明書」

ログインとJWT認証の関係

2段階のプロセス

1段階目:ログイン(身分証明書の発行)

@Post('login')  // 認証不要
login(@Body() loginDto: LoginDto) {
  // 1. ユーザー名・パスワードをチェック
  // 2. 正しければJWTトークン(身分証明書)を発行
  return { accessToken: 'jwt-token-here' };
}

なぜ認証不要?

  • まだJWTトークンを持っていないから
  • ユーザー名・パスワードで本人確認する
  • 成功したらJWTトークンを渡す

2段階目:JWT認証(身分証明書の確認)

@UseGuards(JwtAuthGuard)  // 認証必要
@Get('profile')
getProfile(@Request() req) {
  // JWTトークンで「この人は〇〇さんです」と確認済み
  return req.user;
}

なぜ認証必要?

  • 個人情報を扱うから
  • JWTトークン(身分証明書)で本人確認する
  • 偽造されていないかチェックする

具体的な流れ

実際のやり取り

1. 初回ログイン
Client → Server: POST /auth/login { email, password }
Server → Client: { accessToken: "jwt-token" }

2. 以降のAPIアクセス
Client → Server: GET /api/profile (Authorization: Bearer jwt-token)
Server → Client: { user: { name: "田中", email: "tanaka@example.com" } }

身分証明書の例で理解

1. パスポート申請(ログイン)
あなた → 役所: 「戸籍謄本と住民票を提出」
役所 → あなた: 「パスポートを発行」

2. 海外旅行(JWT認証)
あなた → 空港: 「パスポートを提示」
空港 → あなた: 「確認OK、通過してください」

なぜこの仕組みが必要?

問題1:毎回パスワードを送るのは危険

// ❌ 毎回パスワードを送信(危険)
@Get('profile')
getProfile(@Body() loginDto: LoginDto) {
  // 毎回ユーザー名・パスワードをチェック
}

問題2:サーバーがセッションを覚えるのは大変

// ❌ サーバーがセッション管理(大変)
// 「user123がログイン中」を覚え続ける
// マイクロサービスでは不可能

JWT認証の解決策

// ✅ 安全で効率的
// 1. 最初だけパスワードチェック
// 2. 以降はJWTトークンで確認
// 3. サーバーはセッション情報を保持不要

JWTトークンの中身

実際のJWTトークン

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyLWlkIiwiZW1haWwiOiJ0ZXN0QGV4YW1wbGUuY29tIiwiaWF0IjoxNjM5NTIzNDAwfQ.signature

デコードすると

{
  "sub": "user-id",
  "email": "test@example.com", 
  "iat": 1639523400,
  "exp": 1639609800
}

重要: トークン自体に「誰の」「いつまで有効」が含まれている

認証が必要なAPI vs 不要なAPI

認証不要(誰でもアクセス可能)

@Post('login')     // ログイン処理
@Post('register')  // 新規登録
@Get('public')     // 公開情報
@Get('health')     // ヘルスチェック

認証必要(本人確認が必要)

@Get('profile')         // 個人情報
@Put('profile')         // 個人情報更新
@Get('my-orders')       // 注文履歴
@Post('logout')         // ログアウト
@Delete('account')      // アカウント削除

JWT認証の流れ(完全版)

初回ログイン

1. ユーザー:「メール・パスワードでログインしたい」
2. サーバー:「確認します」→ データベースチェック
3. サーバー:「OK!JWTトークンをどうぞ」
4. ユーザー:JWTトークンを保存

以降のAPIアクセス

1. ユーザー:「プロフィール見たい」+ JWTトークン
2. サーバー:「トークンを確認...OK、田中さんですね」
3. サーバー:「田中さんのプロフィールをどうぞ」

ログアウト後

1. ユーザー:JWTトークンを削除
2. 以降のAPIアクセスは「認証なし」扱い

まとめ

JWT認証とは:

  • ログイン後の身分証明システム
  • 毎回パスワードを送らずに済む仕組み
  • 「この人は確実に〇〇さんです」を証明

ログインとの違い:

  • ログイン: 身分証明書をもらう手続き
  • JWT認証: 身分証明書を見せて本人確認

なぜ必要?

  • セキュリティ(パスワードを毎回送らない)
  • 効率性(サーバーがセッション管理不要)
  • スケーラビリティ(マイクロサービス対応)
つまり:ログイン = 身分証明書発行、JWT認証 = 身分証明書確認
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?