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

タイトル: Middleware内でAuth::check()などを使用する方法
SEOタイトル: Laravel Middleware で Auth を使う完全ガイド

この記事の要点
  • Auth::check() / Auth::user() / Auth::id() は Middleware でも使用可
  • ただしweb ミドルウェアグループに属している必要がある (StartSession / EncryptCookies が前提)
  • API はguard 指定が必須: Auth::guard("sanctum")->check()
  • 未認証時はAuthenticate.php の redirectTo() でリダイレクト先を制御
  • Laravel 11 は bootstrap/app.phpwithMiddleware で登録 (Kernel.php 廃止)

結論: Middleware で Auth ヘルパーを使うコード

<?php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;

class EnsurePremiumUser
{
    public function handle(Request $request, Closure $next): Response
    {
        // 認証チェック
        if (! Auth::check()) {
            return redirect()->route('login');
        }

        // ユーザを取得して属性チェック
        $user = Auth::user();
        if (! $user->is_premium) {
            return redirect()->route('upgrade')
                ->with('error', 'Premium プランが必要です');
        }

        // 認証 ID をログに
        \Log::info('Premium access', ['user_id' => Auth::id()]);

        return $next($request);
    }
}

Auth Facade と Helper の対応

FacadeHelper意味
Auth::check()auth()->check()認証済か (bool)
Auth::user()auth()->user()User モデル (or null)
Auth::id()auth()->id()ユーザ ID (int or null)
Auth::guest()auth()->guest()未認証か
Auth::guard('api')auth('api')ガード指定
Auth::logout()auth()->logout()ログアウト

Middleware Group とセッション

Auth::check() はセッションを使うため、StartSession ミドルウェアが先に動いている必要があります。Laravel のデフォルトでは web グループに StartSession / EncryptCookies が含まれていて、api グループには含まれません。

Laravel 10 以前 (Kernel.php)

// app/Http/Kernel.php
protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,   // ★ これが先に必要
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

    'api' => [
        \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
        \Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];

protected $middlewareAliases = [
    'auth'         => \App\Http\Middleware\Authenticate::class,
    'auth.basic'   => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'premium'      => \App\Http\Middleware\EnsurePremiumUser::class,  // ★ 登録
];

Laravel 11 (bootstrap/app.php)

Laravel 11 では Kernel.php が廃止され、すべて bootstrap/app.php で設定します:

// bootstrap/app.php
return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        api: __DIR__.'/../routes/api.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->alias([
            'premium' => \App\Http\Middleware\EnsurePremiumUser::class,
        ]);

        // web グループに独自ミドル追加
        $middleware->web(append: [
            \App\Http\Middleware\TrackLastActivity::class,
        ]);

        // api グループに Sanctum stateful
        $middleware->statefulApi();
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

ルートでの利用

// routes/web.php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PremiumController;

Route::middleware(['auth', 'premium'])->group(function () {
    Route::get('/dashboard', [PremiumController::class, 'index']);
    Route::get('/reports',   [PremiumController::class, 'reports']);
});

// 単一ルートに付与
Route::get('/profile', [ProfileController::class, 'show'])
    ->middleware('auth');

API での認証 (Sanctum)

API では Cookie セッションではなく Bearer Token を使うため、Auth::guard('sanctum') を明示します:

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;

class CheckApiToken
{
    public function handle(Request $request, Closure $next): Response
    {
        if (! Auth::guard('sanctum')->check()) {
            return response()->json(['error' => 'Unauthenticated'], 401);
        }

        $user = Auth::guard('sanctum')->user();
        $request->setUserResolver(fn () => $user);   // 後続で Auth::user() でも取れるように

        return $next($request);
    }
}

config/auth.php の guards

return [
    'defaults' => [
        'guard'     => 'web',
        'passwords' => 'users',
    ],

    'guards' => [
        'web' => [
            'driver'   => 'session',
            'provider' => 'users',
        ],
        'api' => [                          // 古い形 (passport)
            'driver'   => 'passport',
            'provider' => 'users',
        ],
        'sanctum' => [                      // Sanctum 専用
            'driver'   => 'sanctum',
            'provider' => 'users',
        ],
    ],

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model'  => App\Models\User::class,
        ],
    ],
];

未認証時のリダイレクト先を制御

// app/Http/Middleware/Authenticate.php
namespace App\Http\Middleware;

use Illuminate\Auth\Middleware\Authenticate as Middleware;
use Illuminate\Http\Request;

class Authenticate extends Middleware
{
    protected function redirectTo(Request $request): ?string
    {
        // API 経路はリダイレクトせず JSON 401 を返す
        if ($request->expectsJson()) {
            return null;
        }

        // 管理画面は別のログインへ
        if ($request->is('admin/*')) {
            return route('admin.login');
        }

        return route('login');
    }
}

Closure-based Middleware (Laravel 11)

クラスを作らず、ルートに直接クロージャミドルウェアを書く方法:

// routes/web.php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

Route::get('/admin', function () {
    return view('admin.index');
})->middleware(function (Request $request, Closure $next) {
    if (! Auth::check() || ! Auth::user()->is_admin) {
        abort(403);
    }
    return $next($request);
});

Middleware で Auth が null になる原因

症状原因対処
Auth::check() が常に falseroutes/api.php に置いたweb グループにする or Sanctum guard 指定
Auth::user() が nullSubstituteBindings より前で呼んでいる$middlewareAliases の順序を後ろに
セッションが消えるSESSION_DOMAIN ミス.env の SESSION_DOMAIN を修正
Auth::guard('web')->user() のみ取れるconfig/auth.php で defaults.guard が webguard 明示すれば OK

FAQ

Q: コンストラクタで Auth::user() が null になる
A: Controller のコンストラクタはセッション初期化前なので null。$this->middleware(function ($request, $next) {...}) パターンで参照するか、メソッド内で呼びます。

Q: API でも CSRF ミドルが効いて 419 になる
A: routes/api.php に置いたか、bootstrap/app.php の statefulApi 設定を見直してください。

Q: Auth::user() の型を Phpstan が User として認識しない
A: /** @var \App\Models\User $user */ で型ヒント追加、または config/auth.php の providers.users.model が正しいか確認。