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

Riari's avatar

Laravel 5.1 Authorization - Guest users

Hi,

I'm using the authorization features in 5.1.11 in a package, and so far it's working great except for one thing: I need non-authenticated users to be represented as guests.

I can see that the Gate class calls a user resolver, which appears to be set somewhere in AuthServiceProvider, and as per the docs, "The Gate will automatically return false for all abilities when there is not an authenticated user..."

I know it's designed to be used on authenticated users, but I think there are definitely some cases where being able to check authentication in some way as part of authorization would be beneficial. I'm just not sure how to go about it.

It seems like I have the following options:

  • Extend the Gate class to tweak the user resolution and use that in my package instead
  • Register a custom user resolver than returns a guest user object if the user isn't authenticated

Any other ideas? :)

Thanks

0 likes
9 replies
mikebronner's avatar

Perhaps use Policy-based checks, and if there is no user, then treat them as guest?

Riari's avatar

Unfortunately that won't help because Policy-based checks ultimately use Gate::check(), which is where the user resolution happens. Seems like I need to either override that method, or do something with the user resolver somewhere along the line before the Gate class is used.

Riari's avatar

I've found a solution... here's what I did:

  1. Change the package service provider to extend Illuminate\Foundation\Support\Providers\AuthServiceProvider
  2. Override the registerAccessGate() method:
    /**
     * Register the access gate service for the package.
     *
     * @return void
     */
    protected function registerAccessGate()
    {
        $this->app->bindShared(GateContract::class, function ($app) {
            return new Gate($app, function () use ($app) {
                if (!$app['auth']->check()) {
                    return (object) ['id' => 0];
                }

                return $app['auth']->user();
            });
        });
    }

This works, and using bindShared() means the registered policies are still picked up. However, because it changes the binding in the container, it affects authorization in the host application too.

To overcome that, I could apply a name property to the route group containing all of the forum routes and move the $this->app->bindShared() call into a conditional checking the current request route for that name. I could also provide a config option to toggle "Limit guest authorization to forum routes only" and use that too.

That feels wrong though, and I'm not sure what other side effects there might be (if any). I could really use some guidance here from someone who knows more about the authorization classes than I do!

pmall's avatar

Can you describe a use case of this ? Why a guest should have authorization for something ?

Riari's avatar

Example: a guest should have authorization to read threads in a forum category, but not create or reply to them.

I'm not convinced that authorization should even depend on authentication state in the first place, since a guest is still a user, but that's just how I see it :)

Riari's avatar

Okay, I've decided to leave this out of my package. As much as I'd like to make implementing private categories/forums as straightforward as possible for developers utilising the package, it's proving to be too complicated and unwieldy.

Instead, I'll make my policies and controllers exclude authorisation when showing content by default. It's then up to the host application to make the necessary overrides for changing that behaviour if desired.

Problem solved - sort of :)

1 like
stevenbauman's avatar

Encountering this now. Looks like the only solution at the moment is to use the policy($model) helper to provide some type of "authorization" for guests.

malhal's avatar

This happened to me when a user came in through auth:api maybe there is a way to make a custom userResolver for the policy?

1 like
jrseliga's avatar

I just released a package that allows permission logic to be applied to guest users. It slightly modifies Laravel's Authorization to return a Guest object instead of null when no user is resolved. Also every authorization check now makes it to the Gate instead of failing authorization instantly because there isn't an authenticated user.

Please or to participate in this conversation.