この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:3
ページ更新者:T
更新日時:2026-06-11 07:07:02

タイトル: ルートの認証化
SEOタイトル: Laravel ルート認証化完全ガイド — middleware と Gate

この記事の要点
  • Laravel のルートに認証を掛けるには middleware("auth") を付与
  • API 認証は auth:sanctum / auth:api / auth:passport
  • メール認証必須は verified、認可は can:ability,Model
  • ゲスト専用 (ログイン後アクセス不可) は guest middleware
  • 細かい認可は Gate / Policy、Form Request の authorize() でリクエスト単位に

基本: auth middleware

ログイン必須にしたいルートに auth middleware を付けます:

// routes/web.php
use App\Http\Controllers\DashboardController;

// 単一ルートに付与
Route::get('/dashboard', [DashboardController::class, 'index'])
    ->middleware('auth')
    ->name('dashboard');

// グループに一括付与
Route::middleware('auth')->group(function () {
    Route::get('/profile', [ProfileController::class, 'show']);
    Route::put('/profile', [ProfileController::class, 'update']);
    Route::delete('/account', [AccountController::class, 'destroy']);
});

// プレフィックス + 名前空間 + middleware
Route::middleware(['auth', 'verified'])
     ->prefix('admin')
     ->name('admin.')
     ->group(function () {
        Route::get('/users', [Admin\UserController::class, 'index'])->name('users.index');
     });

未ログインで /dashboard にアクセスすると /login へリダイレクトされます。

認証 guard の指定

middleware用途備考
authWeb セッション認証デフォルト guard
auth:sanctumSPA / API トークンLaravel 推奨
auth:apiPassport API トークン (旧)Passport 利用時
auth:adminカスタム guard (admin)config/auth.php で定義
auth.basicHTTP Basic 認証クイック保護用
verifiedメール認証済のみauth と併用
guest未ログインのみlogin / register 画面用
password.confirmパスワード再確認センシティブ操作前

API ルート (Sanctum)

// routes/api.php
Route::middleware('auth:sanctum')->group(function () {
    Route::get('/user', fn(Request $r) => $r->user());
    Route::apiResource('posts', PostController::class);
});

// 公開API + 認証必須API を併存
Route::get('/public/posts', [PublicPostController::class, 'index']);
Route::middleware('auth:sanctum')->get('/private/posts', [PrivatePostController::class, 'index']);

認可: can middleware

「自分の投稿しか編集できない」等の所有者チェックは Policy + can middleware:

// routes/web.php
Route::put('/posts/{post}', [PostController::class, 'update'])
    ->middleware(['auth', 'can:update,post']);

// app/Policies/PostPolicy.php
namespace App\Policies;

use App\Models\Post;
use App\Models\User;

class PostPolicy
{
    public function update(User $user, Post $post): bool
    {
        return $user->id === $post->user_id;
    }
}

// app/Providers/AuthServiceProvider.php
protected $policies = [
    Post::class => PostPolicy::class,
];

Form Request での authorize()

// app/Http/Requests/PostUpdateRequest.php
class PostUpdateRequest extends FormRequest
{
    public function authorize(): bool
    {
        // route("post") が暗黙バインドの Post モデル
        return $this->user()->id === $this->route('post')->user_id;
    }

    public function rules(): array
    {
        return ['title' => 'required|max:100'];
    }
}

authorize()false を返すと 403 Forbidden

ゲスト専用ルート

ログイン済ユーザーが /login にアクセスしたら /dashboard へリダイレクトしたい:

// routes/web.php
Route::middleware('guest')->group(function () {
    Route::get('/login', [LoginController::class, 'show'])->name('login');
    Route::post('/login', [LoginController::class, 'store']);
    Route::get('/register', [RegisterController::class, 'show'])->name('register');
    Route::post('/register', [RegisterController::class, 'store']);
});

// app/Http/Middleware/RedirectIfAuthenticated.php
public function handle($request, Closure $next, ...$guards)
{
    foreach ($guards as $guard) {
        if (Auth::guard($guard)->check()) {
            return redirect('/dashboard');
        }
    }
    return $next($request);
}

ログイン後リダイレクト先のカスタマイズ

// app/Http/Middleware/Authenticate.php
protected function redirectTo($request)
{
    if (! $request->expectsJson()) {
        return route('login');
    }
}

// LoginController で 認証成功後のリダイレクト
protected $redirectTo = '/dashboard';

// または method override
protected function redirectTo()
{
    return Auth::user()->isAdmin
        ? '/admin'
        : '/dashboard';
}

SPA + Sanctum パターン

// config/sanctum.php
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS',
    'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000')),

// routes/api.php
Route::middleware(['auth:sanctum'])->group(function () {
    Route::get('/me', fn(Request $r) => $r->user());
});
// フロント (Vue / React) 側
// CSRF Cookie を取得
await axios.get('/sanctum/csrf-cookie');

// ログイン
await axios.post('/login', { email, password });

// 認証必須 API
const res = await axios.get('/api/me');

middleware の組合せ実例

// 管理画面: 認証 + メール認証 + 管理者ロール + パスワード再確認
Route::middleware([
    'auth',
    'verified',
    'role:admin',
    'password.confirm:120',  // 120分以内に再確認
])->prefix('admin')->group(function () {
    Route::get('/users/{user}/destroy', [Admin\UserController::class, 'destroy'])
        ->middleware('can:delete,user');
});

FAQ

Q: middleware を全ルートに掛けたい
A: app/Http/Kernel.php$middleware (グローバル) または $middlewareGroups (web/api) に登録。

Q: 認証エラー時に JSON を返したい
A: Authenticate::redirectTo() 内で $request->expectsJson() を判定。null を返すと自動で 401 JSON。

Q: 複数 guard を OR で組合せたい
A: auth:web,admin のようにカンマ区切り。どちらかに通れば OK。

Q: middleware の順番は重要?
A: 重要。authverifiedcan の順が一般的。auth 前に can を置くと user が null でエラー。