Laravelでユーザー登録・ログイン後のリダイレクト先を変更する方法

1688 回閲覧されました

みなさんこんにちは、jonioです。

Laravelはログインするとデフォルトで「Laravelのプロジェクト > resources > views > dashboard.blade.php」(↓の画像のページ)に移動する設定になっています。

これを他のページに変更する方法を説明します。

おすすめ参考書

基礎力を上げるのに一番おすすめです。

Laravelのバージョン

8系で解説しますが10系でも動作しました。

使用ライブラリ

ログイン・ユーザー登録に使ったライブラリはBreezeです。

他のライブラリを使った場合に今回と同じ方法でできるかは分かりません。

ログイン後・ユーザー登録後のリダイレクト先を固定する

「Laravelのプロジェクト > app > Providers > RouteServiceProvider.php」を修正しますがデフォルトは↓になっているはずです。

<?php

namespace App\Providers;

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;

class RouteServiceProvider extends ServiceProvider
{
    /**
     * 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';

    /**
     * The controller namespace for the application.
     *
     * When present, controller route declarations will automatically be prefixed with this namespace.
     *
     * @var string|null
     */
    protected $namespace = 'App\\Http\\Controllers';

    /**
     * Define your route model bindings, pattern filters, etc.
     *
     * @return void
     */
    public function boot()
    {
        $this->configureRateLimiting();

        $this->routes(function () {
            Route::prefix('api')
                ->middleware('api')
                ->namespace($this->namespace)
                ->group(base_path('routes/api.php'));

            Route::middleware('web')
                ->namespace($this->namespace)
                ->group(base_path('routes/web.php'));
        });
    }

    /**
     * Configure the rate limiters for the application.
     *
     * @return void
     */
    protected function configureRateLimiting()
    {
        RateLimiter::for('api', function (Request $request) {
            return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
        });
    }
}

20行目の「/dashboard」を「/index」とか「/index/admin」とかの自分が使いたいURLにすればログイン後に表示するページを変更する事ができます。

ログイン後のリダイレクト先を動的にする

RouteServiceProvider.phpを修正する場合のリダイレクト先は固定になりますが場合によっては条件によってリダイレクト先を変えたい場合があります。

今回は権限でリダイレクト先を変えます。

「Laravelのプロジェクト > Http > Controllers > Auth > AuthenticatedSessionController.php」のstoreメソッドを修正します。

public function store(LoginRequest $request)
{
  $request->authenticate();

  $request->session()->regenerate();


  //下記の行を削除
  return redirect()->intended(RouteServiceProvider::HOME);
  //ここから追加
  $roleTypeId = Auth::user()->role_type_id;
    
  if ($roleTypeId == 1) {
    return redirect('/admin/index');
  } else {
    return redirect('/task/index');
  }
  //ここまで追加
}

これでリダイレクト先を動的に変更できます。

リダイレクトした時にタブにページ名を設定する場合

これはおまけです。

リダイレクトする時にページのタブにページ名を設定しないとURLが表示されて変な感じになるので下記のようにページ名を表示します。

先ほど修正した「AuthenticatedSessionController.php」に追記します。

public function store(LoginRequest $request)
{
  $request->authenticate();

  $request->session()->regenerate();

  $roleTypeId = Auth::user()->role_type_id;
    
  if ($roleTypeId == 1) {
    return redirect('/admin/index')->with('title', '管理画面');    //「->with('title', '管理画面')」を追加
  } else {
    return redirect('/task/index')->with('title', 'タスク一覧');       //「->with('title', 'タスク一覧')」を追加
  }
}

9行目の「$roleTypeId == 1」の場合でデモを見せます。

「/admin/index.blade.php」を下記にします。

<x-layout/>

<div>
    index.blade.phpです。
</div>

「Laravelのプロジェクト > views > components > layout.blade.php」のheadタグを修正します。

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="{{ asset('/css/app.css') }}">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
    <title>
        @if(session('title'))
            {{ session('title') }}
        @endif
    </title>
</head>

これでログインしてリダイレクトをする時にページのタブにtitleタグの内容が表示されますが画面を再読み込みするとtitleタグの内容が表示されなくなります。

そこでlayout.blade.phpを修正します。

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="{{ asset('/css/app.css') }}">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
    <title>
        @if(session('title'))
            {{ session('title') }}
            
        
        //ここから追加
        @elseif($title)
            {{ $title }}
        //ここまで追加
        
        
        @endif
    </title>
</head>

13行目・14行目はページを表示する時に$titleの内容を表示する為の記述です。

「/admin/index.blade.php」を表示するアクションに「$title」の記述をします。

public function index(){
  view()->share('title', '管理画面');         //この行を追加

  return view('admin.index');
}

これでログインしてリダイレクトする時・画面を再読み込みした時のどちらでもページのタブにページ名を表示できます。

ログイン済みでもう一度ログインしようとした場合のリダイレクト

「Laravelのプロジェクト > app > Http > Middleware > RedirectIfAuthenticated.php」を修正します。

デフォルトは下記になっています。

<?php

namespace App\Http\Middleware;

use App\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class RedirectIfAuthenticated
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
     * @param  string|null  ...$guards
     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
     */
    public function handle(Request $request, Closure $next, ...$guards)
    {
        $guards = empty($guards) ? [null] : $guards;

        foreach ($guards as $guard) {
            if (Auth::guard($guard)->check()) {
                return redirect(RouteServiceProvider::HOME);
            }
        }

        return $next($request);
    }
}

変更するのは26行目の「RouteServiceProvider::HOME」です。

これをリダイレクトさせたいルートに変更すればいいです。

例えば下記です。

if (Auth::guard($guard)->check()) {
  return redirect('/task/index');
}

ユーザー登録後のリダイレクト先を動的にする

RegisteredUserControllerのstoreメソッドを修正します。

ファイルの一番下に下記の記述があるはずです。

return redirect(RouteServiceProvider::HOME);

それよりも前の行にリダイレクトする記述をします、例えば下記です。

public function store(Request $request): RedirectResponse
{
  $request->validate(
    [
      'name' => ['required', 'string', 'max:255'],
      'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:'.User::class],
      'password' => ['required', 'confirmed', Rules\Password::defaults()],
    ],
  );

  $role_type_id = User::count() == 0 ? 1 :2;        //この行を追加

  $user = User::create([
    'name' => $request->name,
    'email' => $request->email,
    'password' => Hash::make($request->password),
    'role_type_id' => $role_type_id                    //この行を追加
  ]);

  event(new Registered($user));

  Auth::login($user);


  //ここから追加
  if ($user->role_type_id == 1) {
    return redirect('/admin');
  } elseif ($user->role_type_id == 2) {
    return redirect('/mypage');
  }
  //ここまで追加
  

  return redirect(RouteServiceProvider::HOME);
}