Authentication with AshGraphQL for specific queries/mutations
Maybe I'm missing something, but I'm sure what is the correct approach to check and halt a GraphQL query/mutation inside AshGraphQL.
Right now I already have access to my actor, but there is no verification if the actor is really there or if it is
nil
.
What I thought about doing is just add a policy to check if the actor is nil
or not to the queries/mutations that need to be logged, but I'm not sure if that is the right approach or if there is a better/correct way.22 Replies
Is this for your hand-written graphql queries or for the stuff produced by ash_graphql?
produced by ash_graphql
There is a builtin
actor_present/0
check that you can use
if you want a resource to only be usable by logged in users always, for example, you can say
Ah, got it, so creating a policy to it is the correct approach
Hmm, one problem with that is that I can't easily differentiate an API not being authorized because of some other policy or because the user is not logged in or the token expired...
🤔 Yeah, good point. I've been wanting to make it so that policies can fail with a "reason" so you can bubble information like that up
I still think it ought to be done at the resource level though. If you want to distinguish for now, you could do something like this:
And of course you could define those changes/preparations as a module
Lemme look into what adding custom policy failure reasons would look like.
Might be good to see how others have dealt with this using ash_graphql (perhaps their entire graphql api requires users to be authenticated, at which point you can just do that with a plug)
Yeah, that would be a workaround, but my apis to login/signup are also in graphql so that would not work in my case 😅
https://hexdocs.pm/absinthe/Absinthe.Middleware.html
You can add an absinthe middleware that requires authentication except on those mutations
I feel like you've had more than a few things that have pointed out some improvements we can make to
ash_graphql
, but those improvements all seem doable so hopefully we can get you to a point where you don't need as much escape hatch/funky stuff.I will take a look at that, thanks!
In the meantime, this is working for me:
And
It will result in this error:
👍 It's on my list to look at adding special error messages for policies failing.
So, I was looking at the middleware documentation, seems to me like that is the correct approach, I can see how I can add it to my custom queries/mutations, but I'm not so sure how to "inject" them in queries/mutations created directly from AshGraphql.
Looking at ash graphql code, seems like there is a middleware option when creating queries and mutations https://github.com/ash-project/ash_graphql/blob/58eb725802d4eb3dbcf8630c636bcbb0cd972e4c/lib/resource/resource.ex#L409
So I guess it would be something like this?
You can't add middleware in ash_graphql's configuration
You would do something like this: https://hexdocs.pm/absinthe/Absinthe.Middleware.html#module-object-wide-authentication
Something like this:
Yeah, I created this middleware
And I can see that it is being called and I can see the
GOT HERE!!
message in the terminal.
The problem is that even though I set the result with an error, the action is still being called (since it will fail in the action policies step).
I'm trying to understand why this is that since I believe the execution should have stopped after the put_result
call.
@Zach Daniel Do you know if the policies step is done via a middleware in AshGraphql?
Seems like all middleware will run anyway, so I believe that's why it is reaching the policies
I believe this is the middleware: AshGraphql.Graphql.Resolver
Interesting...I wonder if there is a
halt
feature in absinthe resolutionSeems like the correct approach is to correctly pattern match in all middlewares
For example, I changed the Resolver middleware like this:
Now it works fine
Can you push that change to AshGraphql?
Yes, will do. Do you want to make that PR? Its your idea, don't want to take credit for your fix
happy to do it if you'd rather not though
Ah, I don't care about credits, just having this working is enough for me 😂
Sounds good, will push it up
Btw, this is the topic where the author is saying that this is the correct approach https://elixirforum.com/t/how-to-stop-a-field-resolution-after-a-middleware-returns-an-error/24388/8
Should I use master branch for now until a new version is out?
I just published a new version
Amazing! Thanks
You only need this functionality to send a different error message if the actor is not defined? Everything else could be done with just policies right? Just curious because we are doing everything with policies right now. And I want to be sure I did not misunderstand something and expose something by accident.
Yes, only when an actor is not defined