Describe the bug
I've been trying out Laravel Airlock instead of using Passport for its simplicity. But I'm either not doing correctly, or there is something I'm missing out as I can't get it to authenticate the user in the Lighthouse context. All the @can directives will fail too.
I installed Airlock as per their README, and then I switched all my protected endpoints to use @guard(with: ["airlock"]):
extend type Query {
getConversationMessages(conversationId: ID!): [ConversationMessage!]!
@can(ability: "view", find: "conversationId", model: "App\\Conversation")
@guard(with: ["airlock"])
}
The first thing I noticed is that I couldn't use $context->user() in my queries/mutations. Just using Auth::user() did the trick. I switched my tests to use Airlock::actingAs(factory(User::class)->create()); for authentication, and all my tests passed. I assumed everything was working as expected, to my surprise one of our developers told me the endpoints that were protected with @can were all failing.
Digging into the code I found that the problem was, in the end, the first one that I noticed: the context doesn't have the user. The line that is making @can not working is the one where we call for $context->user() which is null, so the queries will never be authorized.
https://github.com/nuwave/lighthouse/blob/master/src/Schema/Directives/CanDirective.php#L94
Expected behavior/Solution
I would expect that using @guard(with: ["airlock"]) it would inject the user to the context.
Steps to reproduce
@can directiveEnvironment
Lighthouse Version: 6.13.1
Laravel Version: 4.8
This might be related to #1191
@ipalaus i'm using airlock however i'm using it with the @middleware directive. Try switching it from airlock to auth:airlock
Here is a sample of what I'm using
@middleware(checks: ["auth:airlock"])
@sicsol hmm! that's a change I did because I read in the documentation that they were deprecating @middleware and we should be using @guard.
https://github.com/nuwave/lighthouse/blob/master/CHANGELOG.md#deprecated-1
https://github.com/nuwave/lighthouse/blob/master/UPGRADE.md#v4-to-v5
From what I read on #1135 my code should work, but I guess @spawnia will know better.
I've tried switching @guard(with: ["airlock"]) to @guard(with: ["auth:airlock"]) and I get a
"debugMessage": "Auth guard [auth:airlock] is not defined.",.
That said, switching back to @middleware(checks: ["auth:airlock"]) works as expected.
Also, the current documentation:
https://lighthouse-php.com/4.10/security/authentication.html#global
does not work, as longs as it links to the non-existing Laravel documentation.
@ipalaus @sicsol I am having issues with Lighthouse and Sanctum (formerly Airlock). With a simple API route (not using lighthouse) this works
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
But for a Lighthouse request that uses the same request headers and cookies.
"errors":[{"message":"Unauthenticated.","extensions":{"guards":[null],"category":"authentication"}...,"data":{"users":null}}
I'm using Laravel 7, and dev-master of Lighthouse as it has the PR above but I also tried the latest version with no luck
Any ideas?
EDIT: Solved. I did not add EnsureFrontendRequestsAreStateful::class to Lighthouse middleware.
I just released https://github.com/nuwave/lighthouse/releases/tag/4.11.0
Note that @guard does not log in users.
To ensure the user is logged in, add the AttemptAuthenticate middleware to your lighthouse.php
middleware config, see the default config https://github.com/nuwave/lighthouse/blob/master/src/lighthouse.php for an example.
@schrapel can you give us more hints? We are unable to get Lightouse auth working with Sanctum. We want users to login via standard Laravel UI (outside of Lighthouse, so standard web guard). We only want to share the cookie-based session with Lighthouse and verify user is logged in on every request. Is this also your case?
I'm using sanctum and the following directive works:
extend type Query @guard(with: "sanctum") {
me: User @auth
}
I'd like to add this example to the documentation.
Edited: Lighthouse uses the application's default guard setting, so basically settings config/auth.php > guards > api > driver to sanctum (or airlock ) is enough
Most helpful comment
@ipalaus @sicsol I am having issues with Lighthouse and Sanctum (formerly Airlock). With a simple API route (not using lighthouse) this works
But for a Lighthouse request that uses the same request headers and cookies.
I'm using Laravel 7, and dev-master of Lighthouse as it has the PR above but I also tried the latest version with no luck
Any ideas?
EDIT: Solved. I did not add
EnsureFrontendRequestsAreStateful::classto Lighthouse middleware.