はじめに
Laravel × Reactを使用してSPA開発を行った際に認証機能でLaravel Sanctumをしたのでその備忘録です。少しでもお役に立てば幸いです。内容に誤りがありましたら、ご指摘いただけると大変ありがたいです
Laravel Sanctumとは
LaravelアプリでシンプルにAPI認証やSPA認証を実現するための公式パッケージ。Laravel Sanctumを使用すれば、軽量で柔軟なAPI認証を実装することができます。
(特徴)
APIトークン認証
- ユーザーごとに複数のAPIトークンを発行可能
- トークンごとに権限設定可能(例. 投稿用トークン、閲覧用トークンなど)
SPA認証(Cookieベース)
- 同一ドメイン/サブドメインで安全にログイン状態を保持
- Vue, React などのSPAと相性が良い
API認証
API認証とは、「APIトークン」を使って認証する方式です。ユーザーがログインするとサーバー側でトークン文字列を発行します。クライアントはそのトークンをHTTPヘッダー
につけてリクエストを行います。
(特徴)
- Stateless: Cookieやセッションを使わず、トークンのみで認証
- ドメインが異なっても使用可能
- トークンごとに権限を付与が可能
(基本構成)
1. インストール
composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate
2. モデル設定
ユーザーモデルにHasApiToken
を追加
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
}
3. APIトークン利用例
//生成したトークンをフロントに返す
$token = $user->createToken('my-token', ['create', 'update'])->plainTextToken;
// 認証付きAPIルート
// routes/api.php
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
4. クロスオリジンの設定
下記コマンドを実行すると、`cors.php'ファイルがconfigフォルダの中に生成されます。
php artisan config:publish cors
'allowed_origins' => ['your-frontend-domain'],
5. ヘッダーで送信
Authorization: Bearer {token}
SPA認証
SPA認証とは、Cookieやセッションを使って認証する方式です。クライアント(Vue, Reactなど)がログインリクエストを行うと、Laravel側でセッションを作成し、Cookieに保存します。そのCookieを使ってクライアントからリクエストがおくられてきたらログイン済みかを判断します。
(特徴)
- Stateful: Cookieやセッション利用
- 同一ドメイン or サブドメインのみ使用可能
- Cookieは自動的に送信される
(基本構成)
1. インストール
composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate
2. モデル設定
ユーザーモデルにHasApiToken
を追加
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
}
3. 認証用コントローラー
// app/Http/Controllers/Auth/SPAAuthController.php
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
class SPAAuthController extends Controller
{
public function login(Request $request)
{
$cred = $request->validate([
'email' => ['required','email'],
'password' => ['required'],
]);
if (! Auth::attempt($cred, true)) {
return response()->json(['message' => 'Invalid credentials'], 422);
}
// セッションID再生成(セキュリティ)
$request->session()->regenerate();
return response()->json(['message' => 'Logged in']);
}
public function me(Request $request)
{
return $request->user(); // 認証済みならUser返却
}
public function logout(Request $request)
{
Auth::guard('web')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return response()->json(['message' => 'Logged out']);
}
}
4. ルーティング
// routes/web.php
use App\Http\Controllers\Auth\SPAAuthController;
Route::post('/login', [SPAAuthController::class, 'login']);
Route::post('/logout', [SPAAuthController::class, 'logout'])->middleware('auth:web');
Route::middleware('auth:web')->get('/user', function (Request $request) {
return $request->user();
});
5. .envの設定(例)
SESSION_DOMAIN=.example.com
SANCTUM_STATEFUL_DOMAINS=app.example.com,api.example.com
6. SPA認証のCSRF準備(React)
/sanctum/csrf-cookie
を踏んでから /login する必要があります
// axios例
await axios.get('/sanctum/csrf-cookie');
await axios.post('/login', { email, password });
API認証 vs SPA認証
項目 | API認証 | SPA認証 |
---|---|---|
認証方法 | Bearerトークン | セッションCookie |
状態管理 | Stateless | Stateful |
クロスドメイン | OK | 不可(同一ドメイン/サブドメインのみ) |
主な用途 | モバイル・外部API | Web SPA |
最後に
最後までご覧いただきありがとうございました!