Home » Php » php – Laravel Auth::hasUser always false in Global Scope

php – Laravel Auth::hasUser always false in Global Scope

Posted by: admin February 25, 2020 Leave a comment

Questions:

I have the following code in my model:

protected static function boot()
{
    parent::boot();

    static::addGlobalScope(new CompanyScope);
}

Here is my CompanyScope:

class CompanyScope implements Scope
{
    public function apply(Builder $builder, Model $model)
    {
        \Log::info('apply');

        if (Auth::hasUser()) {
            \Log::info('auth');

            $builder->where($model->getTable() . '.company_id', company()->id);
        }
    }
}

In my log, I only see apply, I do not see auth, nor is the scope being applied.

Why?

How to&Answers:

I just tested what you have here except I’ve used \Illuminate\Support\Facades\Log rather than \Log and it seems it works fine as long as you are actually testing it with the authenticated user:

app/User.php

<?php

namespace App;

use App\Scopes\CompanyScope;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    protected static function boot()
    {
        parent::boot();

        static::addGlobalScope(new CompanyScope);
    }
}

app/Scopes/CompanyScope.php

<?php

namespace App\Scopes;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Illuminate\Database\Eloquent\Scope;

class CompanyScope implements Scope
{
    public function apply(Builder $builder, Model $model)
    {
        Log::info('apply');

        if (Auth::hasUser()) {
            Log::info('auth');

            $builder->where($model->getTable() . '.company_id', company()->id);
        }
    }
}

In my controller I just fetch the user with id 1:

/**
* Get landing view.
*
* @return \Illuminate\Http\JsonResponse
*/
public function index(): JsonResponse
{
    $user = User::find(1);

    return new JsonResponse([
        'user' => $user,
    ]);
}

and the corresponding test:

/**
 * @test
 */
public function global_scope()
{
    $this->actingAs($user = factory(User::class)->create(['id' => 1]));

    $this->assertTrue($user->exists);
    $this->assertAuthenticatedAs($user);

    $response = $this->get(route('home'));

    $response->assertExactJson([
        'user' => $user->toArray()
    ]);
}

After running the test, my log file contains:

[2020-02-16 14:18:59] testing.INFO: apply  
[2020-02-16 14:18:59] testing.INFO: auth 

If you try the same without logging the user in, then only apply will be logged.