Laravel 如果经过身份验证的中间件则重定向

Laravel Redirect If Authenticated middleware

我的应用程序有三种类型的用户,每种都有自己的 dashboard。我需要检查管理员或任何其他用户是否无法看到其他用户仪表板。

有一个中间件 RedirectIfAuthenticated :

public function handle($request, Closure $next, $guard = null){

    if (Auth::guard($guard)->check() && auth()->user()->type == 'admin'){
        return redirect('/admin');
    }

    if (Auth::guard($guard)->check() && auth()->user()->type == 'author'){
        return redirect('/author');
    }

    if (Auth::guard($guard)->check() && auth()->user()->type == 'client'){
        return redirect('/client');
    }
}

它在 guest 中间件下。

上面的代码对我来说似乎不错但是当我测试它时,浏览器显示Too many redirects

我做错了什么,最好的处理方法是什么。

需要稍微修改一下代码

public function handle($request, Closure $next, $guard = null){

        if (Auth::guard($guard)->check() && auth()->user()->type == 'admin'){
            return redirect('/admin');
        }

        if (Auth::guard($guard)->check() && auth()->user()->type == 'author'){
            return redirect('/author');
        }

        if (Auth::guard($guard)->check() && auth()->user()->type == 'client'){
            return redirect('/client');
        }
        return $next($request);
}

你必须为每个 if 语句添加一个额外的检查,看看你是否已经在它要重定向到的路由上

可能是这样的:

&& $request->is('admin')

只需拆分您的支票并保留原始支票return:

     public function handle($request, Closure $next, $guard = null){
             if (Auth::guard($guard)->check()){

               if(Auth::user()->type == 'admin'){
                    return redirect('/admin');
               }
               if(Auth::user()->type == 'author'){
                    return redirect('/author');
               }
               if(Auth::user()->type == 'client'){
                    return redirect('/client');
               }
            }
            return $next($request);
    }

您可能误解了该中间件的用途。 RedirectIfAuthenticated 的目的是将用户重定向到他们的默认身份验证页面。这并不是要阻止 unauthenticated/unauthorised 用户访问特定区域。

你需要做的是在没有授权的情况下重定向。由于这是一个简单的案例,您可以只使用一个中间件:

class RequireRole {
     public function handle($request, Closure $next, $role) {
          abort_unless(auth()->check() && auth()->user()->type == $role, 403, "You don't have permissions to access this area");
           return $next($request);
     }
}

然后在你的Kernel.php

中注册这个中间件
protected $routeMiddleware = [
        //Other middleware
        "requirerole" => RequireRole::class
];

然后你可以在你的路线中使用它,例如

Route::get('/admin', function () { /* action */ })->middleware("requirerole:admin");

但是,如果您发现自己需要更复杂的规则,请查看 Authorization

正如接受的答案中所指出的,中间件的目的是在用户通过身份验证后重定向他。

现在,如果您检查 App\Http\Kernel.php,您将看到中间件附加到 guest 路由中间件变量。

因此,您分配给来宾中间件的任何路由都不会被经过身份验证的用户访问。

要解决您的问题,请按照已接受答案中的指示创建另一个中间层。

What you need to do is redirect if not authorised. Since this is a simple case you can just have a middleware:

    public function handle($request, Closure $next, $role) {
        abort_unless(auth()->check() && auth()->user()->type == $role, 403, "You don't > have permissions to access this area");
          return $next($request);
    }
}

Then register this middleware in your Kernel.php

      //Other middleware
       "requirerole" => RequireRole::class
];

Then you can use it in your routes e.g.

Route::get('/admin', function () { /* action */ })->middleware("requirerole:admin");

实际上,除非不可避免,否则您可能不需要修改 laravel 附带的默认文件。