【Laravel】同一ブラウザでユーザー画面と管理画面をセッション分離して共存させる方法
はじめに
Laravelでユーザー向けと管理者向けの画面を用意することはよくありますが、同じブラウザ上で両方に同時ログインしようとしても、セッションが衝突してしまいログインできないという問題に直面します。
この記事では、AuthガードとセッションのCookie名を分離することで、ユーザー画面と管理画面を同一ブラウザでセッションを共存させる方法を解説します。
対象者
- Laravelでユーザーと管理者のログイン機能を分けたいエンジニア
- 同じブラウザ上でログイン状態を干渉させずに共存させたい方
- セッションやガードの動作をより深く理解したい方
なぜセッションが衝突するのか
Laravelのセッションは、基本的に1つのCookie(通常は laravel_session
)を使って保存されています。
そのため、同じブラウザでユーザーと管理者がそれぞれログインすると、セッションが上書きされ、一方のログインが強制的に解除される事象が発生します。
前提
-
本記事は、Laravel Webアプリケーションを開発中の方を対象にしています。執筆時点での想定バージョンは Laravel 10.x です。
-
管理者用とユーザー用のルートが、別々に構成されている(例:
routes/web.php
とroutes/admin.php
を分離) -
すべての対象ルートが
web
ミドルウェアグループで定義されている(session/cookie/CSRFを有効にするため) -
セッションドライバに
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_session
とuser_session
が共存していることを確認
おわりに
私も以前、Laravelで管理者とユーザーを分離したシステムを開発していた際、ログインが一方しか保持されない問題に悩まされました。この方法にたどり着くまでに試行錯誤しましたが、セッションの仕組みを把握し、ミドルウェアでCookieを分けることで解決できました。本記事が同じような悩みを持っている方のヒントになれば嬉しいです。
株式会社ONE WEDGE
【Serverlessで世の中をもっと楽しく】
ONE WEDGEはServerlessシステム開発を中核技術としてWeb系システム開発、AWS/GCPを利用した業務システム・サービス開発、PWAを用いたモバイル開発、Alexaスキル開発など、元気と技術力を武器にお客様に真摯に向き合う価値創造企業です。
Discussion