Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

CGuy's avatar
Level 5

Ignore Global scopes for Auth

Hi,

I'm building a website where users are able to make their profile private or public. I order to achieve this I applied a global scope that filters users who set their profile to private.

This causes problems when authenticating and when using auth()->user() as users will not be found even though they exist but are private.

Is a custom User Provider / Guard necessary or is there a simpler way?

Thanks

0 likes
7 replies
SaeedPrez's avatar

Hm, can you explain a little more how your global scope works and why is it global and not a local scope for the users or profile model?

CGuy's avatar
Level 5

I applied a Privacy Trait to the User model in order to filter all users that do not have a public profile through the app.

public function apply(Builder $builder, Model $model)
    {
    $builder->where('privacy', 'public');
    }

I don't want to apply this as a local scope as this is used every time on every query.

The issue is that users with a private profile are not able to login as the query won't return them. I'm looking for a way to apply (withoutGlobalScopes()) to the query that retrieves the User when authenticating.

davielee's avatar
davielee
Best Answer
Level 11

Well, you could implement a user provider that extends the base EloquentUserProvider and then override the methods you need to remove that global scope.

class CustomUserProvider extends EloquentUserProvider
{
    public function retrieveById($identifier)
    {
        return $this->createModel()->newQuery()->withoutGlobalScopes()->find($identifier);
    }
}

I only did one as an example, but that is the basic idea. To activate it for use you have to take a little trip to the AuthServiceProvider.

Auth::provider('custom', function ($app, $config) {
    return new CustomUserProvider($app['hash'], $config['model']);
});

Then you have to change your auth config.

'providers' => [
    'users' => [
        'driver' => 'custom',
        'model' => App\User::class,
    ],
]
7 likes
SaeedPrez's avatar

Perhaps it would be better and easier to create another User model, maybe calling it PublicUser where you apply this global scope and use that in your project.

$users = PublicUser::where('foo', 'bar')->get();

You could leave the default User be used for the authentication.

2 likes
CGuy's avatar
Level 5

@craigpaul Thanks. This is exactly what I was looking for.

@SaeedPrez I thought about this but I don't want to handle multiple User models through the App. Implementing a custom User Provider doesn't require any code change elsewhere.

CGuy's avatar
Level 5

Is there a way to check if auth has run without checking if there is a user logged in?

Please or to participate in this conversation.