Laravel 7 __construct 中的用户数据

Laravel 7 User data in __construct

使用Laravel 7。 在控制器构造函数中,我希望能够访问当前用户的详细信息,这样我就可以将主站点小部件(按钮链接等)和自定义用户小部件加载到一个中以显示在视图中

use Illuminate\Support\Facades\Auth;

...

    $widgets = Cache::get("widgets");
    $usersdata = Cache::get("userdata");
    $this->middleware('auth');
    $widgets = array_merge($widgets, $usersdata[Auth::user()->id]["widgets"]);
    View::share([
        "widgets" => json_encode($widgets)
    ]);

然而,在这个阶段,从研究来看,用户数据不可用(即使经过身份验证?)。 不确定访问它的最佳方法,或者更好的做法可能是覆盖中间件身份验证(在哪里?),以便它可以 return 用户 ID 或其他内容,例如:

$userid=$this->middleware('auth');

我希望在构造函数中使用相同的方法,因此所有扩展该主控制器的控制器都可以使用相同的方法。

这是 laravel 的预期行为,您可以阅读更多相关信息 here

Laravel collects all route specific middlewares first before running the request through the pipeline, and while collecting the controller middleware an instance of the controller is created, thus the constructor is called, however at this point the request isn’t ready yet.

你可以找到泰勒背后的推理here:

It’s very bad to use session or auth in your constructor as no request has happened yet and session and auth are INHERENTLY tied to an HTTP request. You should receive this request in an actual controller method which you can call multiple times with multiple different requests. By forcing your controller to resolve session or auth information in the constructor you are now forcing your entire controller to ignore the actual incoming request which can cause significant problems when testing, etc.

所以一个解决方案是 create a new middleware 然后将其应用于所有路由,就像这样,其中 widgets 是您的新中间件:

Route::group(['middleware' => ['auth', 'widgets']], function () {
    // your routes
});

但如果您真的想将它保留在构造函数中,您可以实施以下解决方法:

class YourController extends Controller
{
    public function __construct(Request $request)
    {
        $this->middleware('auth');
        $this->middleware(function ($request, $next) {
            $widgets = Cache::get("widgets");
            $usersdata = Cache::get("userdata");
            $widgets = array_merge($widgets, $usersdata[$request->user()->id]["widgets"]);

            View::share([
                "widgets" => json_encode($widgets)
            ]);

            return $next($request);
        });
    }
}