Hi, I'm writing some tests for my API that uses Laravel Passport and I have a problem with not having ability to log out the Guard. If I try to run Auth::logout() on my logout api endpoint it will throw an error: Call to undefined method Illuminate\Auth\RequestGuard::logout(). I use instead Auth::user()->token()->revoke(); to log out user in my code. However when I write test, Guard::check() still returns true and original user and ->dontSeeIsAuthenticated('api') fails. Is there a way to perform full logout immediately so Guard will return false on Guard::check() on next code line?
Today I faced the same problem.
+1
@vedmant I found the workaround. I override the RequestGuard and add the method for unset/logout user:
class CustomRequestGuard extends Illuminate\Auth\RequestGuard
{
public function unsetUser()
{
$this->user = null;
}
}
Also override PassportServiceProvider as well and implement method makeGuard where you will create instance of your CustomRequestGuard.
protected function makeGuard(array $config)
{
return new CustomRequestGuard(function ($request) use ($config) {
return (new TokenGuard(
$this->app->make(ResourceServer::class),
Auth::createUserProvider($config['provider']),
$this->app->make(TokenRepository::class),
$this->app->make(ClientRepository::class),
$this->app->make('encrypter')
))->user($request);
}, $this->app['request']);
}
After that you are able to call auth()->unsetUser(); anywhere for logging out.
@akalongman Yeah, this will work, but it's too much hassle just to test one logout feature.
+1
This isn't possible. There's a difference between a stateful guard (like web) and a stateless guard (like api). Stateless guards are for short lived sessions which don't persist into other requests (like api tokens for api calls). These don't offer logout functionality because the session will expire immediately after the call. That's why you don't have a logout method.
If you need to revoke the token during your call you can't call any auth functionality after revoking it. This seems purely a way of where some logic is implemented wrong.
For this particularly use case I'd say that checking auth state with Auth::check() isn't useful. It might be better to simply check if the token was revoked.
Also: revoking token doesn't necessarily mean that the current session was made invalid. It just means that the token was revoked for the next session.
Please feel free to provide feedback if you think I'm wrong somewhere with my above statements.
Most helpful comment
This isn't possible. There's a difference between a stateful guard (like web) and a stateless guard (like api). Stateless guards are for short lived sessions which don't persist into other requests (like api tokens for api calls). These don't offer logout functionality because the session will expire immediately after the call. That's why you don't have a logout method.
If you need to revoke the token during your call you can't call any auth functionality after revoking it. This seems purely a way of where some logic is implemented wrong.
For this particularly use case I'd say that checking auth state with
Auth::check()isn't useful. It might be better to simply check if the token was revoked.Also: revoking token doesn't necessarily mean that the current session was made invalid. It just means that the token was revoked for the next session.
Please feel free to provide feedback if you think I'm wrong somewhere with my above statements.