在Laravel 5.3中的父构造函数中访问Auth [复制]

在Laravel 5.3中的父构造函数中访问Auth [复制]

问题描述:

This question already has an answer here:

Im working on an app in Laravel 5.3. I have created an AppController. I would like for all of my controllers to extend AppController so that they all share a few common properties and methods.

Given the below 2 implementations below, my intention is to set the current user to $this->user when AppController is constructed so it will be available to all controllers extending AppController.

I expect that when I call \App\Http\Controllers\User\PermissionController@test I should get my user object dumped twice. Once when AppController is initialized, and again when PermissionController@test is called.

However, inside of AppController __construct(), $this->user is always NULL while PermissionController@test dumps the user as expected.

AppController:

<?php

    namespace App\Http\Controllers\App;

    use App\Http\Controllers\Controller;

    class AppController extends Controller
    {
        /**
         * The current user when logged in
         * @var \User
         */
        protected $user;

        public function __construct()
        {
            if(\Auth::check() ) {
                $this->user = \Auth::user();
            }
            var_dump($this->user);
        }
    }

PermissionController:

<?php

    namespace App\Http\Controllers\User;

    use App\Http\Controllers\App\AppController;

    class PermissionController extends AppController
    {
        public function test()
        {
            if(\Auth::check() ) {
                // Do something
                $this->user = \Auth::user() ;
            }
            var_dump($this->user);
        } 
    }

If it matters, I'm using https://github.com/Adldap2/Adldap2-Laravel to auth against Active Directory.

Clearly I'm misunderstanding something hear. Why does AppController __construct() not dump the user?

</div>

This is because of changes in Laravel 5.3. If you need to use Auth in constructor you need to do it like so:

public function __construct()
{
     $this->middleware(function ($request, $next) {
             if(\Auth::check() ) {
                $this->user = \Auth::user();
            }
            var_dump($this->user);

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

This change was described in upgrade guide to Laravel 5.3 - https://laravel.com/docs/5.3/upgrade#upgrade-5.3.0 look at section Session In The Constructor

The controller construct executes before any middleware, so there is no user yet (https://laravel.com/docs/5.3/upgrade#upgrade-5.3.0)

You can use closure middleware as described in the guideline.

From the docs

In previous versions of Laravel, you could access session variables or the authenticated user in your controller's constructor. This was never intended to be an explicit feature of the framework. In Laravel 5.3, you can't access the session or authenticated user in your controller's constructor because the middleware has not run yet

As an alternative, you may define a Closure based middleware directly in your controller's constructor. Before using this feature, make sure that your application is running Laravel 5.3.4 or above:

public function __construct()
{
    $this->middleware(function ($request, $next) {
        $this->user = auth()->user();

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

Please check my answer here.

You need to move this check in middleware if you're using Laravel 5.3