背景
Laravel標準のログイン機能を使わずに認証機能を実装している環境で、ログイン後に直前画面にリダイレクトする挙動を実装したかった
もっと言うと構成がこんな感じ↓で
Route::get('/login', 'AuthController@index')->name('login');
Route::post('/login', 'AuthController@auth')
Route::middleware('auth:web')->group(function () {
Route::get('/home', function () {
return view('home');
});
}
こんな感じ↓のログインフローがしたかった
[GET]/home:トップページ
↓ ※未認証時にログインページへリダイレクト
[GET] /login :ログイン入力画面
↓
[POST]/login :ログイン認証
↓ ※最初にアクセスしてきたページ(/home)にリダイレクト
[GET]/homeトップページ
結論
1.ログイン画面に遷移した時にリファラ情報を読み取ってセッションに書き込み
2.ログインが済んだらセッションからリファラ情報を読み取ってそこにリダイレクトすればOK
実装前の状態
public function index(Request $request)
{
// ログイン済みユーザーはRouteServiceProvider::HOMEへリダイレクト
if (Auth::check()){
return redirect(RouteServiceProvider::HOME);
}
return view('login');
}
public function auth(Request $request)
{
//login
Auth::login(User::find($request->id));
//laravel defaultのルートにリダイレクト
retun redirect(RouteServiceProvider::HOME);
}
こんな感じの実装をしていたとしたら
実装後の状態
public function index(Request $request)
{
// ログイン済みユーザーはRouteServiceProvider::HOMEへリダイレクト
if (Auth::check()){
return redirect(RouteServiceProvider::HOME);
}
// -------差分ここから-------
// login画面に移る前の画面の情報をセッションに保存
if (!strpos(url()->previous(), 'login') && (parse_url(url()->previous())['host'] === $request->getHttpHost())) session(['url.intended' => url()->previous()]);
// -------ここまで-------
return view('login');
}
public function auth(Request $request)
{
//login
Auth::login(User::find($request->id));
// -------差分ここから-------
//redirect
$redirectPath = session('url.intended', RouteServiceProvider::HOME);
return redirect($redirectPath);
// -------ここまで-------
}
こうすればOK
解説
書き込み部分
if (!strpos(url()->previous(), 'login') && (parse_url(url()->previous())['host'] === $request->getHttpHost())) session(['url.intended' => url()->previous()]);
左辺の!strpos(url()->previous(), 'login')
は
url()->previous()
でリファラ情報を取得して
strpos(, 'login')
で文字列の中にloginがないか、
つまり/loginにアクセスしてくる前の画面が/loginじゃなかったかを確認
右辺の(parse_url(url()->previous())['host'] === $request->getHttpHost()))
は
parse_url(url()->previous())['host']
で前の画面のホストを取得
$request->getHttpHost()
で今のログイン画面のホストを取得
つまり、前の画面と今の画面が同じホストか確認
まとめると、
/loginにアクセスしてくる前の画面が/loginじゃないかつ前の画面と今の画面が同じホストの場合、セッションに前の画面情報を書き込んでいる
リダイレクト部分
$redirectPath = session('url.intended', RouteServiceProvider::HOME);
return redirect($redirectPath);
$redirectPath = session('url.intended', RouteServiceProvider::HOME);
でセッションにリファラ情報があればリファラ情報を、なければデフォルトパスを$redirectPathに書き込みしている
以上。