第26回: JWTによる認証 — ステートレスな「自己完結するトークン」の仕組み

章: 第3章: RESTful API設計

セッションを使わない認証が必要な場面、ありますか?

複数サーバーで負荷分散するAPIや、モバイルアプリとWeb API間の認証では、サーバー側にセッションを持つと状態管理が複雑になります。「どのサーバーがセッションを持っているか」を共有するためにRedisやスティッキーセッションが必要になるからです。

JWT(JSON Web Token)はトークン自体にユーザー情報を含めることで、サーバー側にセッションを持たずに認証できます。

JWTの実装


<?php
use Tymon\JWTAuth\Facades\JWTAuth;

// ログイン: トークン発行
$credentials = ['email' => $email, 'password' => $password];
if (!$token = auth()->attempt($credentials)) {
    return response()->json(['error' => '認証失敗'], 401);
}
return response()->json(['token' => $token]);

// 保護ルートでのユーザー取得
$user = JWTAuth::parseToken()->authenticate();

セッション認証 vs JWT認証

観点 セッション認証 JWT認証
サーバー状態 セッションDB/Redisが必要 不要(ステートレス)
スケールアウト セッション共有の仕組みが必要 そのまま複数サーバーに対応
トークン失効 セッション削除で即時無効 有効期限まで有効(ブラックリスト対応要)
ペイロード サーバーが管理 トークン自体にユーザー情報を格納

チェックポイント: JWTはペイロードがBase64エンコードされているだけで暗号化はされていません。パスワードや機密情報をペイロードに入れないようにしてください。

Laravelでの設定


<?php
// config/auth.php のガード設定
'api' => [
    'driver'   => 'jwt',
    'provider' => 'users',
],

// ルート保護
Route::middleware('auth:api')->get('/profile', function () {
    return response()->json(auth()->user());
});

// リフレッシュトークン
Route::middleware('auth:api')->post('/refresh', function () {
    return response()->json(['token' => auth()->refresh()]);
});

チェックポイント: JWTの有効期限は短め(15〜60分)にし、リフレッシュトークンで更新する設計が一般的です。有効期限を長くするとトークン漏洩時のリスクが高まります。

まとめ & 次のステップ

  • JWTはトークン自体にユーザー情報を持つステートレスな認証方式
  • 複数サーバー・マイクロサービス構成でセッション管理の複雑さを回避できる
  • ペイロードに機密情報を入れず、有効期限を短くする設計が重要

次回はレート制限の実装を学びます。APIへの過剰なリクエストを制御し、サービスを守る仕組みです。

Related Articles