前提
Laravel6.x
PHP7以上
$ composer require laravel/ui "^1.0" --dev
$ php artisan ui vue --auth
上記コマンドにて認証機能を作成したこと
参考:https://readouble.com/laravel/6.x/ja/authentication.html
目的
初回ログイン時のURLを条件分岐させたいという事がありました。
LoginControllerの確認
LoginController.phpには必要最低限のコードしか書かれていません。
そのため、Illuminate\Foundation\Auth\AuthenticatesUsers
を確認します。
※単純に/home
を変更したければRouteServiceProvider.php
のHOMEを変更すれば良いです。
class RouteServiceProvider extends ServiceProvider
{
protected $namespace = 'App\Http\Controllers';
/**
* The path to the "home" route for your application.
*
* @var string
*/
public const HOME = '/hoge';
...
...
}
AuthenticatesUsers.phpの確認
ここにはログイン関連の処理が書かれているようでした。
trait AuthenticatesUsers
{
use RedirectsUsers, ThrottlesLogins;
...省略
public function login(Request $request)
{
$this->validateLogin($request);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
if (method_exists($this, 'hasTooManyLoginAttempts') &&
$this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if ($this->attemptLogin($request)) {
return $this->sendLoginResponse($request);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}
...省略
ここでバリデーションなどを行い、最終的にログインに成功したらsendLoginResponse
を呼んでるのでそれを見に行きます。
protected function sendLoginResponse(Request $request)
{
$request->session()->regenerate();
$this->clearLoginAttempts($request);
return $this->authenticated($request, $this->guard()->user())
?: redirect()->intended($this->redirectPath());
}
ここでintendedの返り値のURLにリダイレクトするようですね。
引数に入っている$this->redirectPath()
が今回の目的です。
redirectPath()の確認
RedirectsUsers
というトレイトの中に記載されていました。
trait RedirectsUsers
{
/**
* Get the post register / login redirect path.
*
* @return string
*/
public function redirectPath()
{
if (method_exists($this, 'redirectTo')) {
return $this->redirectTo();
}
return property_exists($this, 'redirectTo') ? $this->redirectTo : '/home';
}
}
ここでは、
- redirectToという関数があればその返り値を返す
- もしなければredirectToというプロパティを返す
- それもなければ'/home'を返す
という処理が実装されているので、二つのやり方がありそう。
-
redirectPath()
をオーバーライドする -
redirectTo()
を定義する
のどちらかでしょうか。
(ベストプラクティスはどちらなんでしょう。redirectTo()
を定義する方なのかな。ご教示いただけると幸いです。)
ちなみに最初にHOME
を変えれば良いと書いたのは、redirectTo
というプロパティだったからです。
寄り道ですが、AuthenticateUsers.php
のintended
メソッドは何かというと、
public function intended($default = '/', $status = 302, $headers = [], $secure = null)
{
$path = $this->session->pull('url.intended', $default);
return $this->to($path, $status, $headers, $secure);
}
こんな感じ。
簡潔に言うと、ログイン前のURLがセッションに保存されていたらそのURLを返すよという事です。
pullとかtoが何をしているかは見ればわかると思います。
public function pull($key, $default = null)
{
return Arr::pull($this->attributes, $key, $default);
}
url.intended
のセッションが無ければ$default
を返すという事です。
どこまで掘り下げればいいかわからなくなったので、気になる方はソースコードを読むと良いと思います。
参考:https://readouble.com/laravel/6.x/ja/helpers.html
目的のredirectPath()のオーバーライド
public function redirectPath()
{
if ('foo' === 'foo') {
return '/foo';
} else {
return '/bar'
}
}
もしくは、こっち。
(個人的にはこっちの方が良いと思います。)
public function redirectTo()
{
if ('foo' === 'foo') {
return '/foo';
} else {
return '/bar'
}
}
これで初回ログイン時の分岐ができると思います。
間違いなどがありましたらご指摘をお願いします!