Laravel - 用户未通过身份验证时如何重定向到所需页面

Posted

技术标签:

【中文标题】Laravel - 用户未通过身份验证时如何重定向到所需页面【英文标题】:Laravel - How to redirect to a desired page when user is not authenticated 【发布时间】:2016-03-09 11:28:43 【问题描述】:

我正在尝试使用扩展类中的 __constructor (AdminController extends AdminBaseController) 但显然它不起作用,我不知道可以使用什么,在这里你可以看到我的两个类:

AdminBaseController.php

class AdminBaseController extends Controller

    public function __construct()
        if (!Auth::user())
            return view('admin.pages.login.index');
        
    

AdminController.php

class AdminController extends AdminBaseController

    public function __construct()
        parent::__construct();
    

    public function index()
    
        return view('admin.pages.admin.index');
    

    public function ajuda()
    
        return view('admin.pages.admin.ajuda');
    

编辑


这是我的admin 路由组:

Route::group([
    'prefix' => 'admin',
    'middleware' => 'auth'
], function () 
    Route::get('/', 'Admin\AdminController@index');

    Route::get('login', 'Admin\AuthController@getLogin');
    Route::post('login', 'Admin\AuthController@postLogin');
    Route::get('logout', 'Admin\AuthController@getLogout');

    Route::group(['prefix' => 'configuracoes'], function () 
        Route::get('geral', 'Admin\AdminConfiguracoesController@geral');
        Route::get('social', 'Admin\AdminConfiguracoesController@social');
        Route::get('analytics', 'Admin\AdminConfiguracoesController@analytics');
    );

    Route::get('ajuda', 'Admin\AdminController@ajuda');
);

【问题讨论】:

你不会在 AdminController::construct() 中做任何事情,所以你可以避免编写它,并且类将使用他的父构造函数。从问题不清楚:问题是什么? @Moppo 我有很多用于管理区域的控制器,为了避免代码重复,我正在考虑验证用户是否使用 AdminBaseController 中的 __constructor 进行身份验证 好的。您应该使用中间件来检查用户是否是管理员 我已经发布了一个解释如何使用中间件的答案 【参考方案1】:

为此使用中间件,然后在控制器构造函数中使用它,如下例所示。

public function __construct()

    $this->middleware('guest', ['except' => 'logout']);

然后您需要保护您希望用户登录访问的路由。

Route::group(['middleware' => 'auth'], function() 
      Route::get('/dashboard', 'DashboardController@index');
);

【讨论】:

我对 php/laravel 完全不熟悉,而且我自己从来没有使用过中间件,查看文件我可以看到一个名为 Authenticate 的中间件,其中有一个名为 handle 的函数,可能我可以用吗?【参考方案2】:

您扩展和执行父收缩器的方式是正确的,但是 只有通过路由、控制器操作和过滤器才能返回视图以执行它。否则你必须调用 send()。

出于你的目的,我认为你应该在过滤器http://laravel.com/docs/4.2/routing#route-filters之前使用

【讨论】:

是的,因为 Denis saide 中间件也是 laravel5 的绝佳等待【参考方案3】:

控制器不是检查用户是否通过身份验证的正确位置。您应该为此使用中间件。要了解什么是中间件,请查看here

让我们看看如何使用默认的 Laravel 的 auth 中间件来实现此目的:

首先摆脱你的AdminBaseController,只使用AdminController

然后你必须检查auth中间件在文件app\Http\Kernel.php中是否启用

你应该有这行:

protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,

这意味着中间件已激活并可用于您的路由。

现在让我们进入app\Http\Middleware\Authenticate.php 中的中间件类来指定中间件的行为:

//this method will be triggered before your controller constructor
public function handle($request, Closure $next)

    //check here if the user is authenticated
    if ( ! $this->auth->user() )
    
        // here you should redirect to login 
    

    return $next($request);

现在剩下要做的就是决定应该应用中间件的路由。假设您有两条路由,您希望只能由经过身份验证的用户访问,您应该指定以这种方式为这两条路由使用中间件:

Route::group( ['middleware' => 'auth' ], function()

    Route::get('admin/index', 'AdminController@index');
    Route::get('admin/ajuda', 'AdminController@ajuda');
);

【讨论】:

发现小问题,实现后提交表单时,刷新页面... 问题是:postLogin 也在中间件里面,因为它在管理员组里面,我编辑我的答案给你看我的路线 我已经解决了从admin 路由中删除admin/login 路由的问题,这是正确的方法吗? 完全正确:postLogin 应该在经过身份验证的路由组之外,因为用户在提交表单时仍未通过身份验证【参考方案4】:

在 Laravel 5.5 中,未经身份验证的用户将导致 Authenticate 中间件抛出 AuthenticationException 异常。

protected function authenticate(array $guards)

 if (empty($guards))
 
  return $this->auth->authenticate();
 
 foreach ($guards as $guard) 
  if ($this->auth->guard($guard)->check()) 
      return $this->auth->shouldUse($guard);
  
 
 throw new AuthenticationException('Unauthenticated.', $guards);

这将被 app/Exceptions/Handler 类捕获,该类将调用其 render 方法,该方法负责将给定的异常转换为 HTTP 响应。

public function render($request, Exception $exception)

 return parent::render($request, $exception);

App/Exceptions/Handler 扩展了 'Illuminate\Foundation\Exceptions\Handler',位于 '/vendor/laravel/src/Illuminate/Foundation/Exceptions/Handler' 中。它有自己的渲染方法。在该渲染方法中,有一个 if else 声明。

elseif ($e instanceof AuthenticationException)

 return $this->unauthenticated($request, $e);

下面是上面在同一个类中调用的‘unauthenticated’方法

protected function unauthenticated($request, AuthenticationException $exception)

  return $request->expectsJson() ? response()->json(['message' => $exception->getMessage()], 401) : redirect()->guest(route('login'));

在此方法中,您可以重定向未经身份验证的用户。

据我所知,这就是幕后发生的事情。

【讨论】:

以上是关于Laravel - 用户未通过身份验证时如何重定向到所需页面的主要内容,如果未能解决你的问题,请参考以下文章

Laravel sanctum 检查用户是不是在没有重定向的情况下通过身份验证

Flask - 如果当前用户未通过身份验证,如何重定向到登录页面?

Laravel 5.5登录后重定向到特定路由

如果未通过身份验证,则颤振 Web 重定向用户

Laravel 登录重定向您的次数过多

如果用户未登录 Laravel,则重定向到登录页面