Laravel - 在控制器构造之后调用的中间件

Laravel - Midlleware called after controller construct

编辑:更好的例子

我在使用在 SectionsController 构造函数之后调用的 checkauth 控制器时遇到问题 - 这是扩展的 ReportController,我不知道为什么它会这样工作。 我尝试在 SectionController 构造的开头添加中间件,例如 $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;
    }

}

来自 route:list

的输出
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

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

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

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

编辑 您可以将 Laravel 中间件用于策略,而不是在构造函数中执行所有错误的操作。这需要您使用 Authorize 中间件,该中间件按标准启用。

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