Hey there,
I'm loosing my mind right now, as I can't figure out what I'm doing wrong. I already went down the call stack until the point where I see what's wrong/missing, but I can't find out how this should ever work.
First, our setup: It's pretty much following the guidance here: https://laravel.com/docs/8.x/passport (We're using Passport v10.2.2)
-
User model uses the HasApiTokens trait (not that I would need a user, as we're using the client credentials grant, but ok)
- The
api guard is using the passport driver (which uses the "users" provider. Again, don't think we would care)
- We have
'client' => CheckClientCredentials::class added to the $routeMiddleware and added 'client' to the api group in $middlewareGroups!
- Also, we have the
auth:api middleware added to the api $middlewareGroups group, so all our APIs are using the api guard we set in auth.php!
- The only addition we made is a custom client model, but this properly extends the
Client model from Passport and simply only adds a relation to a "vendor" table we have. And we are telling Passport to use it in theAuthServiceProvider::boot() method: Passport::useClientModel(OAuthClient::class);
We can successfully obtain tokens using the client credentials grant, that's no issue at all.
The actual issue we see is that all requests we do using a client credential access token are 401 Unauthorized. I went down the call stack and ended up scratching my head when looking at the TokenGuard::authenticateViaBearerToken() method, as it will just return if it can't find a user using the PassportUserProvider for an oauth_user_id, which is never set for a request done with a client grant access token. And just returning here will make the RequestGuard::check() / RequestGuard::user() not do anything and with that, Authenticate::authenticate() just call unauthenticated()...
So for me, it looks like TokenGuard::authenticateViaBearerToken() will only work for personal access tokens, but will never work for client credentials access tokens...
HOWEVER: If I remove the auth:api middleware, so effectively not have it use the passport driver, it works! And it's actually validating the tokens (I tried providing invalid/expired/no tokens and it doesn't work. So it does something useful, but I didn't go down the call stack for this yet...). But it's now using the SessionGuard... I don't know if that is expected or not
I must be doing something wrong or missing something. Maybe somebody can point me in the right direction.
Thanks and greetings,
Andy!