【问题标题】:Laravel - Midlleware called after controller constructLaravel - 在控制器构造后调用的中间件
【发布时间】:2020-08-14 22:01:39
【问题描述】:

编辑:更好的例子

我遇到了在 SectionsController 构造函数之后调用的 checkauth 控制器的问题 - 这是扩展的 ReportController,我不知道为什么它会这样工作。 我尝试在 SectionController costruct 的开头添加中间件,例如 $this->middleware('checkauth'); 但也不起作用。

中间件

<?php

namespace App\Http\Middleware;

use Closure;
use Auth;


class CheckAuth
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (!Auth::check())
        {
            return redirect('/admin/login')->withErrors(['message' => 'You need to login before proceeding']);
        }

        return $next($request);
    }
}

节控制器

<?php

namespace App\Http\Controllers\RMReport;

use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Support\Facades\View;
use App\Http\Controllers\Controller;
use Illuminate\Http\UploadedFile;



class SectionsController extends BaseController
{
  use AuthorizesRequests, DispatchesJobs, ValidatesRequests;

   protected $user;

    public function __construct(){
      $this->middleware('checkauth');

      dump("SECTIONSCONTROLLER: ");
      dump(\Auth::check());

     //PROBLEM HERE - \Auth::Check is false , \Auth::user is null
     $this->user = \Auth::user();

     if( !$this->user->can('something') ) return redirect()->route('someroute');
}
}

报表控制器

<?php

namespace App\Http\Controllers\RMReport\Form;

use App\Http\Controllers\RMReport\SectionsController;
use Illuminate\Http\Request;
use Illuminate\Support\Str;


class ReportController extends SectionsController
{

    public function form(){
      if( $this->user->status != 'Active'){
        return something;
      }
    return another something;
    }

}

从路由列表输出

GET|HEAD | admin/remote-report/{id?} | rm.report | App\Http\Controllers\RMReport\Form\ReportController@form | web,checkauth,checkownerRMreport |  
POST | admin/remote-report/{id?} | rm.report | App\Http\Controllers\RMReport\Form\ReportController@store | web,checkauth,checkownerRMreport |

调用 GET 输出

"SECTIONSCONTROLLER: "

false

"CHECKAUTH:"

true

【问题讨论】:

  • 您是否只是想知道为什么 dump(\Auth::check());false,即使它是在 -&gt;middleware('checkauth')call 之后调用的,还是您的代码还有更多内容?
  • 感谢您的回复。我需要保存有关用户(用户对象和一些关系)的构造信息。从这个控制器(SectionsController)继承其他控制器(例如ReportController),然后我需要在这个控制器中使用这些信息。所以是的,我想知道为什么是 false 以及如何在控制器之前调用中间件以便下次使用控制器构造中的 Auth 信息。

标签: php laravel laravel-5 middleware laravel-middleware


【解决方案1】:

了解Laravel 生命周期和对象生命周期很重要。创建新对象时,将首先调用构造函数。当 new SectionsController() 的动作发生时,会立即触发构造函数,由于构造函数调用了中间件,它无法知道它应该先运行。

这意味着在请求生命周期中,控制器构造函数必须在中间件之前。幸运的是,这个问题已经解决了,如果你在构造函数中使用中间件依赖逻辑的回调,你将避免这个问题。

$this->middleware(function ($request, $next) {
    dump("SECTIONSCONTROLLER: ");
    dump(\Auth::check());
});

编辑 您可以使用Laravel 中间件进行策略,而不是在构造函数中做所有错误的事情。这需要您使用 Authorize 中间件,该中间件按标准已启用。

$this->middleware('can:something');

【讨论】:

  • 感谢您的回复...这项工作用于转储,但是当我需要在回调之后使用 Autch::check in 构造时,我得到了相同的结果。可能我没有正确理解 Laravel 生命周期。我认为当我在路由(分组路由或路由本身或控制器构造中)定义中间件时,将在控制器类之前创建中间件,而不是称为控制器类构造。另外,如果我在构造中调用 $this->middleware('checkauth') ,它不是 CheckAuth 中间件的回调吗?它给了我同样的结果
  • 你需要在回调中做你的工作,那你想做什么?您的代码示例不包含该示例,请提供示例
  • 非常感谢您的帮助,但出于兴趣,当有人需要像我举的例子那样与用户一起工作时,这能以某种方式做到吗?
  • 我认为你在构造函数中尝试做的事情是错误的,应该在中间件中完成,构造函数不应该处理重定向,而是你的控制器的实例化。
猜你喜欢
  • 2017-05-23
  • 1970-01-01
  • 1970-01-01
  • 2016-08-05
  • 1970-01-01
  • 2019-01-02
  • 2019-03-09
  • 2022-01-14
  • 2018-01-24
相关资源
最近更新 更多