Laravel - 如果未经授权,重定向到登录,即使是路由未注册

Posted

技术标签:

【中文标题】Laravel - 如果未经授权,重定向到登录,即使是路由未注册【英文标题】:Laravel - Redirect to login if not authorised, even is route is not registered 【发布时间】:2019-01-17 04:44:52 【问题描述】:

我正在 Laravel v5.6 中构建一个应用程序,它应该完全位于登录页面后面(登录页面本身和密码重置页面除外)。

我已经写了一个中间件类CheckAuth - 要点是,

public function handle($request, Closure $next)

    if (auth()->guest() && $this->requestIsNotForGuests($request->path())) 
        return redirect()->route('login');
    

    return $next($request);

如果未经身份验证的用户请求未注册的路由,他们会看到 404 页面。未经身份验证的用户不应该知道路由是否存在。

如何将任何未经身份验证的请求(不包括登录页面本身和密码重置页面)重定向到登录页面?

我已经尝试在 routes/web.php 中使用带有中间件的路由组,但这没有按预期工作。


更新...

我在routes/web.php的末尾添加了以下内容,

Route::any('any', function() 
    abort(404);
)->where('any', '.*');

这实现了我所追求但感觉不对的行为 - 有没有更好的方法?

【问题讨论】:

不应该将if 语句改为if (auth()->guest() || $this->isUnauthorisedRequest($request->path())) 所以如果用户是访客或者当前请求路径未经授权,重定向到登录页面 这将导致无限重定向循环。如果客人请求允许的路线,则不需要重定向。 那么您的名为isUnauthorisedRequest 的方法应该能够判断出请求的路径已为所有人授权。您在此处的命名约定并不表示其功能或有问题 好的,我知道它可能会产生误导,我已经更新了方法名称以使其功能更清晰。 【参考方案1】:

您只需将所有路由封装在中间件中。这是非常普遍的做法。您的中间件规定了规则并相应地重定向,如果用户通过身份验证,则重定向到用户尝试访问的路由,如果没有,则重定向到不同的位置/不同的操作。

Route::middleware('auth')->group(function() 
    //Routes you want affected here
);

标准的 Auth 中间件可以解决这个问题,只需将其修改为用户未通过身份验证时想要发生的情况。

编辑

只是一些常识,您的登录页面将在中间件组之外?

** 编辑 2 **

在更好地理解问题后,您正在尝试通过任何路由,即使它不存在通过 auth 中间件。

使用我上面输入的所有信息,您现在需要应用它。

使用标准的身份验证中间件,你不需要改变任何中间件,它会做你需要的事情

按照中间件组中的建议包装您的路由,看看我在上面放的内容,忽略登录路由!

现在在中间件组的outside中添加一个新路由,这将在登录路由之外

Route::get(/slug, 'HomeController@redirector');

我必须强调,这条路线必须是你的 web.php 中的最后一条

现在在 HomeController 中创建一个方法,如下所示:

public function redirector($slug)

    return redirect()->route('login');

【讨论】:

这样做仍然意味着请求不存在路径的访客用户看到的是 404 页面 - 他们不应该 - 他们应该被重定向到登录页面。 这些路由仍然会为每个人定义,如果没有登录的人点击了这些路由,他们只会被重定向到登录页面。您是否看到其他表明他们会得到 404 而不是重定向的东西?可能您的登录页面导致 404? 我认为你误解了我的帖子。我请求的行为是 any 请求(登录名和密码重置除外)重定向到登录。我确实希望为客人显示一个 404 页面。 举个例子——一个应用有两个注册的路由——/login/secret。我需要的行为是,如果客人输入/login 以外的任何内容,他们将被重定向到/login(即使他们输入不存在的路线,例如/made-up)。我的第一次尝试导致了我不想要的 404。客人不应该知道路线是否存在,无论如何他们都应该被重定向到/login。我已经用一个提供所需行为但似乎有点“hacky”的解决方案更新了我的原始帖子。 好的,请看我更新的答案,这对你有用!【参考方案2】:

试试这个:

if (Auth::guest()) 
   return redirect()->route('route_name');

没有return $next($request);(它会导致请求“继续”)。

顺便说一句,你可以创建新的路由文件并在RouteServiceProvider 中注册它。而且你没有指定 Laravel 版本...

【讨论】:

【参考方案3】:

如果您只想显示登录页面而不是 404,您可以修改您的 \App\Exceptions\Handler::render 方法。只需放置

if ($exception instanceof NotFoundHttpException) return redirect('/login');

到这个方法的第一行。还有

use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

当然。

$exception->getCode() === 404 不适合我。

【讨论】:

以上是关于Laravel - 如果未经授权,重定向到登录,即使是路由未注册的主要内容,如果未能解决你的问题,请参考以下文章

如何将所有访客请求重定向到 Laravel 应用程序中的登录页面?

Laravel - 具有多重身份验证的未经身份验证的重定向问题

在 ASP.NET Core 中未经授权时重定向到登录

ASP.NET 核心,更改未经授权的默认重定向

Laravel 未经身份验证无触发

Laravel 7:重定向到不同警卫的不同登录名