🛡️

【Laravel】同一ブラウザでユーザー画面と管理画面をセッション分離して共存させる方法

に公開

はじめに

Laravelでユーザー向けと管理者向けの画面を用意することはよくありますが、同じブラウザ上で両方に同時ログインしようとしても、セッションが衝突してしまいログインできないという問題に直面します。
この記事では、AuthガードとセッションのCookie名を分離することで、ユーザー画面と管理画面を同一ブラウザでセッションを共存させる方法を解説します。

対象者

  • Laravelでユーザーと管理者のログイン機能を分けたいエンジニア
  • 同じブラウザ上でログイン状態を干渉させずに共存させたい方
  • セッションやガードの動作をより深く理解したい方

なぜセッションが衝突するのか

Laravelのセッションは、基本的に1つのCookie(通常は laravel_session)を使って保存されています。
そのため、同じブラウザでユーザーと管理者がそれぞれログインすると、セッションが上書きされ、一方のログインが強制的に解除される事象が発生します。

前提

  1. 本記事は、Laravel Webアプリケーションを開発中の方を対象にしています。執筆時点での想定バージョンは Laravel 10.x です。

  2. 管理者用とユーザー用のルートが、別々に構成されている(例:routes/web.phproutes/admin.php を分離)

  3. すべての対象ルートが web ミドルウェアグループで定義されている(session/cookie/CSRFを有効にするため)

  4. セッションドライバに file, database, redis などを使っている。(cookie や array は非対応)

解決策:セッション名とガードの分離

セッション名(session.cookie)と認証ガードを役割ごとに分離することで、共存可能になります。

1. Authガードとプロバイダの定義

config/auth.php を以下のように編集します。

// config/auth.php
'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'admin' => [
        'driver' => 'session',
        'provider' => 'admins',
    ],
],

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

    'admins' => [
        'driver' => 'eloquent',
        'model' => App\Models\Admin::class,
    ],
],

2. セッション名を分離するミドルウェア

パスに応じてセッションCookie名を切り替えるミドルウェアを作成します。

例:

// app/Http/Middleware/SwitchSessionCookie.php

namespace App\Http\Middleware;

use Closure;

class SwitchSessionCookie
{
    public function handle($request, Closure $next)
    {
        config(['session.cookie' => $request->is('admin/*')
            ? config('session.cookie_admin', 'admin_session')
            : config('session.cookie_user', 'user_session')
        ]);

        return $next($request);
    }
}

3. ミドルウェアの登録

app/Http/Kernel.php にて登録します:

// app/Http/Kernel.php
protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        // 他のミドルウェア
        \App\Http\Middleware\SwitchSessionCookie::class, // ← 追加
    ],
];

4. ログイン・ログアウトの実装例

// app/Http/Controllers/Admin/Auth/AdminLoginController.php

// 管理者ログイン・ログアウト
Auth::guard('admin')->login($admin);
Auth::guard('admin')->logout();

// app/Http/Controllers/Admin/Auth/UserLoginController.php

// ユーザーログイン・ログアウト
Auth::guard('web')->login($user);
Auth::guard('web')->logout();

5. 動作確認のポイント

  • https://example.com/user にアクセスしてユーザーログイン
  • 同じブラウザで https://example.com/admin にアクセスして管理者ログイン
  • Chrome DevTools → アプリケーション → Cookie → ドメインで admin_sessionuser_session が共存していることを確認

おわりに

私も以前、Laravelで管理者とユーザーを分離したシステムを開発していた際、ログインが一方しか保持されない問題に悩まされました。この方法にたどり着くまでに試行錯誤しましたが、セッションの仕組みを把握し、ミドルウェアでCookieを分けることで解決できました。本記事が同じような悩みを持っている方のヒントになれば嬉しいです。


株式会社ONE WEDGE

【Serverlessで世の中をもっと楽しく】
ONE WEDGEはServerlessシステム開発を中核技術としてWeb系システム開発、AWS/GCPを利用した業務システム・サービス開発、PWAを用いたモバイル開発、Alexaスキル開発など、元気と技術力を武器にお客様に真摯に向き合う価値創造企業です。
https://onewedge.co.jp/

GitHubで編集を提案

Discussion