Laravel8 Authのログイン処理って何してるん?
皆さんこんにちは、サーバーサイドエンジニアの大川です。今回はLaravel8の認証処理(ログイン)がどんなことをしているのか簡単にまとめてみたいと思います!(影の目標はログイン後のリダイレクト先をどこで指定しているか知りたいです!)
環境の紹介
laravel8のアプリを作り、下記の方法に沿ってスターターキットのLaravel/Breezeをインストールしました。
https://readouble.com/laravel/8.x/ja/starter-kits.html
一度任意の情報でユーザー登録を行ったらログイン処理をたどってみます。
ログインページ
ログインページのbladeファイルは 「resources/views/auth/login.blade.php」です。ログイン情報をPostしている部分を抜粋して下記に記載します。
<form method="POST" action="{{ route('login') }}">
@csrf
<!-- Email Address -->
<div>
<x-label for="email" :value="__('Email')" />
<x-input id="email" class="block mt-1 w-full" type="email" name="email" :value="old('email')" required autofocus />
</div>
<!-- Password -->
<div class="mt-4">
<x-label for="password" :value="__('Password')" />
<x-input id="password" class="block mt-1 w-full"
type="password"
name="password"
required autocomplete="current-password" />
</div>
<!-- Remember Me -->
<div class="block mt-4">
<label for="remember_me" class="inline-flex items-center">
<input id="remember_me" type="checkbox" class="rounded border-gray-300 text-indigo-600 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" name="remember">
<span class="ml-2 text-sm text-gray-600">{{ __('Remember me') }}</span>
</label>
</div>
<div class="flex items-center justify-end mt-4">
@if (Route::has('password.request'))
<a class="underline text-sm text-gray-600 hover:text-gray-900" href="{{ route('password.request') }}">
{{ __('Forgot your password?') }}
</a>
@endif
<x-button class="ml-3">
{{ __('Log in') }}
</x-button>
</div>
</form>
認証情報の確認
Postされた情報は「routes/auth.php」の下記の処理を通過してコントローラーにたどり着きます。
Route::post('/login', [AuthenticatedSessionController::class, 'store'])
->middleware('guest');
呼ばれているコントローラーは「app/Http/Controllers/Auth/AuthenticatedSessionController.php」で下記のstore関数が実行されます。
/**
* Handle an incoming authentication request.
*
* @param \App\Http\Requests\Auth\LoginRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function store(LoginRequest $request)
{
$request->authenticate();
$request->session()->regenerate();
return redirect()->intended(RouteServiceProvider::HOME);
}
そしてstore関数の中でLoginRequestクラスのauthenticate関数を使って認証情報が一致しているかをチェックします!
/**
* Attempt to authenticate the request's credentials.
*
* @return void
*
* @throws \Illuminate\Validation\ValidationException
*/
public function authenticate()
{
$this->ensureIsNotRateLimited();
if (! Auth::attempt($this->only('email', 'password'), $this->boolean('remember'))) {
RateLimiter::hit($this->throttleKey());
throw ValidationException::withMessages([
'email' => __('auth.failed'),
]);
}
RateLimiter::clear($this->throttleKey());
}
/**
* Ensure the login request is not rate limited.
*
* @return void
*
* @throws \Illuminate\Validation\ValidationException
*/
public function ensureIsNotRateLimited()
{
if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
return;
}
event(new Lockout($this));
$seconds = RateLimiter::availableIn($this->throttleKey());
throw ValidationException::withMessages([
'email' => trans('auth.throttle', [
'seconds' => $seconds,
'minutes' => ceil($seconds / 60),
]),
]);
}
セッションに値をもたせて「app/Providers/RouteServiceProvider.php」の「public const HOME =」で定義されているルートにリダイレクトさせてます。リダイレクト時に実行しているintended関数では意図したURLへのリダイレクトの応答を作成しています!
/**
* The path to the "home" route for your application.
*
* This is used by Laravel authentication to redirect users after login.
*
* @var string
*/
public const HOME = '/dashboard';
「vendor/laravel/framework/src/Illuminate/Routing/Redirector.php」のintended関数と実際のリダイレクト応答を作成しているto関数
/**
* Create a new redirect response to the previously intended location.
*
* @param string $default
* @param int $status
* @param array $headers
* @param bool|null $secure
* @return \Illuminate\Http\RedirectResponse
*/
public function intended($default = '/', $status = 302, $headers = [], $secure = null)
{
$path = $this->session->pull('url.intended', $default);
return $this->to($path, $status, $headers, $secure);
}
/**
* Create a new redirect response to the given path.
*
* @param string $path
* @param int $status
* @param array $headers
* @param bool|null $secure
* @return \Illuminate\Http\RedirectResponse
*/
public function to($path, $status = 302, $headers = [], $secure = null)
{
return $this->createRedirect($this->generator->to($path, [], $secure), $status, $headers);
}
といった感じで追っかけてみました!
ログイン後にリダイレクトされるページを指定したいなら「app/Providers/RouteServiceProvider.php」のHOMEの値を変更するか、新たに定数をpublicで定義してそちらを「app/Http/Controllers/Auth/AuthenticatedSessionController.php」のstore関数のリダイレクト先として設定しても良いかもですね!