Laravel11でマルチログインを実装するためにやるべきことをメモ書き代わりに記載。
- マイグレーション
- モデルとマイグレーションファイルの作成
- 既存UserモデルとUserマイグレーションファイルの内容をコピーして整える
- ガードとプロバイダー設定(config/auth.php)
- 認証関連の設定
- ルート設定
- admin.phpを作成し、web.phpとauth.phpの内容をコピペして修正
- ミドルウェア設定
- 未認証、認証済み時のリダイレクト先の設定
- LoginRequest設定
- 入力したMailアドレスとPasswordが正しいかをDBに問い合わせてチェックする機能の提供
- ルートを見て処理を分ける
- セッション設定
- adminとuserでそれぞれ異なるセッションで管理できるように設定
- コントローラーとブレードをコピペして作成
- Userのコントローラーとブレード一式をコピペして、Admin用のコントローラーとブレードを作成する
マイグレーション
adminのモデルとマイグレーションを作成する。既存のUserのファイルの内容をコピーして名前をadminなどに変更。
php artisan make:model Admin -m
// -m オプションをつけるとマイグレーションファイルも一緒に作成してくれる
作成後、以下のコマンドで反映する
php artisan migrate
ガードとプロバイダー設定(config/auth.php)
config/auth.phpで以下のようにadminのガードを設定
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'user' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
],
以下のようにprovidersにadminsを追加
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
],
ルート設定
route/admin.phpを作成して、route/web.phpとroute/auth.phpの内容をコピーして、必要なところを書き換える
下記のようにviewの先頭にadmin/とつけておく。後でviewsの配下にadminのフォルダを作成して関連ブレードファイルをuserからコピーして作成。
※userフォルダも作成して、既存のファイルを入れておく
Route::get('/', function () {
return view('admin/welcome');
});
下記のように認証関連の部分のミドルウェアの設定をmiddleware(‘auth:admin’)やmiddleware(‘guest:admin’)などに書き換える。設定内容はガード設定と一致する必要がある。
※authはIlluminate\Auth\Middleware\Authenticateのエリアス
※guestはIlluminate\Auth\Middleware\RedirectIfAuthenticatedのエリアス
Route::middleware('auth:admin')->group(function () {
Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
});
作成したadmin.phpルート設定を反映するのに、bootstrap/app.phpの設定を追加する。then:の中で追加。
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__ . '/../routes/web.php',
commands: __DIR__ . '/../routes/console.php',
health: '/up',
then: function () {
Route::middleware('web')
->prefix('admin')
->name('admin.')
->group(base_path('routes/admin.php'));
},
)
->withMiddleware(function (Middleware $middleware) {
//
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
ミドルウェア設定
app/Http/Requests/Providers/AppServiceProvider.phpのbootメソッド(など)で未認証時のリダイレクト先と認証済みのリダイレクト先の設定
※Laravel11ではMiddlewareディレクトリがVender以下に移動され、AuthenticateやRedirectIfAuthenticatedで直接書き換えないで、リダイレクト先をredirectUsingメソッドを通じて行う
※AppServiceProvider.bootメソッドはHTTPリクエストの度に呼ばれる
use Illuminate\Auth\Middleware\Authenticate;
use Illuminate\Auth\Middleware\RedirectIfAuthenticated;
public function boot(): void
{
// 未認証時のリダイレクト先
Authenticate::redirectUsing(function () {
if (Route::is('admin.*')) {
return route('admin.login');
} else {
return route('login');
}
});
// 認証済みのリダイレクト先
RedirectIfAuthenticated::redirectUsing(function () {
if (Route::is('admin.*')) {
return route('admin.dashboard');
} else {
return route('dashboard');
}
});
}
リクエストクラス設定(LoginRequest)
App\Http\Requests\Auth\LoginRequest.phpを編集する。
ログインリクエストでEmailとPasswordを照合して、問題がある時に弾く処理。
public function authenticate(): void
{
$this->ensureIsNotRateLimited();
$attempt = function ($guard) {
if (!Auth::guard($guard)->attempt($this->only('email', 'password'), $this->boolean('remember'))) {
RateLimiter::hit($this->throttleKey());
throw ValidationException::withMessages([
'email' => trans('auth.failed'),
]);
}
};
if ($this->routeIs('admin.*')) {
$attempt('admin');
} else {
$attempt('user');
}
RateLimiter::clear($this->throttleKey());
}
セッション設定
.envファイルに以下のようにセッションのクッキー名を定義する
SESSION_COOKIE="${APP_NAME}_session_user"
SESSION_COOKIE_ADMIN="${APP_NAME}_session_admin"
config/session.phpの設定
'cookie' => env(
'SESSION_COOKIE',
Str::slug(env('APP_NAME', 'laravel'), '_') . '_session_user'
),
'cookie_admin' => env(
'SESSION_COOKIE_ADMIN',
Str::slug(env('APP_NAME', 'laravel'), '_') . '_session_admin'
),
AppServiceProvider.bootメソッドで以下のように設定
// セッションの切り替え
if (request()->is('admin*')) {
config(['session.cookie' => config('session.cookie_admin')]);
}
if (request()->is('owner*')) {
config(['session.cookie' => config('session.cookie_owner')]);
}
コントローラーとブレード作成
adminファイルを作成してUserのコントローラーとブレードをコピペして放り込む
コントローラー設定
AuthenticatedSessionControllerの修正点
public function create(): View
{
return view('admin.auth.login');
}
public function store(LoginRequest $request): RedirectResponse
{
$request->authenticate();
$request->session()->regenerate();
return redirect()->intended(route('admin.dashboard', absolute: false));
}
public function destroy(Request $request): RedirectResponse
{
Auth::guard('admin')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/admin');
}
RegisteredUserControllerの修正点
public function create(): View
{
return view('admin.auth.register');
}
public function store(Request $request): RedirectResponse
{
$request->validate([
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:' . Admin::class],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);
$user = Admin::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
event(new Registered($user));
Auth::login($user);
return redirect(route('admin.dashboard', absolute: false));
}
PasswordResetLinkControllerの修正点
public function create(): View
{
return view('admin.auth.forgot-password');
}
ProfileController.phpの修正点
public function edit(Request $request): View
{
return view('admin.profile.edit', [
'user' => $request->user(),
]);
}
public function update(ProfileUpdateRequest $request): RedirectResponse
{
$request->user()->fill($request->validated());
if ($request->user()->isDirty('email')) {
$request->user()->email_verified_at = null;
}
$request->user()->save();
return Redirect::route('admin.profile.edit')->with('status', 'profile-updated');
}
/**
* Delete the user's account.
*/
public function destroy(Request $request): RedirectResponse
{
$request->validateWithBag('userDeletion', [
'password' => ['required', 'current_password'],
]);
$user = $request->user();
Auth::logout();
$user->delete();
$request->session()->invalidate();
$request->session()->regenerateToken();
return Redirect::to('/admin');
}
ブレード設定
route(‘admin.login’)など、adminの接頭詞をつける。接頭詞はbootstrap/app.php以下の設定と一致する必要がある。
対象ファイル:
- login.blade.php
- register.blade.php
- profile/
- edit.blade.php
- partials/
- delete-user-form.blade.php
- update-password-form.blade.php
- update-profile-information-form.blade.php
then: function () {
Route::middleware('web')
->prefix('admin')
->name('admin.')
->group(base_path('routes/admin.php'));
},
コメント