How to return `401 Unauthorized` status when actor is absent in action?

I just started playing with phoenix/ash and I'm trying to create a simple json api with authentication. I managed to setup the authentication and use the bearer token to get the actor. I have a simple /me action that filters users resource to get the user with the same email as actor:
read :me do
filter expr(email == ^actor(:email))
end
read :me do
filter expr(email == ^actor(:email))
end
But when the actor is absent I get an exception saying that actor must be set. If I understand correctly policies are not designed to handle such cases but rather forbid access to some resources. My question is where and how should i prevent access to that action and how can I return an appropriate status when unauthorized?
13 Replies
kernel
kernel4w ago
assuming you could do something like this with the Ash errors https://hexdocs.pm/phoenix/custom_error_pages.html#custom-exceptions but for cases where the actor is not even present - I think the best stage to do that would be in the router pipeline no? a plug which validates the bearer token exists and is valid
gerdziu
gerdziuOP4w ago
The actor is not present when the bearer token is not set in the authorization header.
kernel
kernel4w ago
are you using ash_authentication / ash_json_api ?
gerdziu
gerdziuOP4w ago
yeah both
kernel
kernel4w ago
assuming they come with the proper plugs, otherwise you need to write your own that checks if a bearer token is set, and if not, halt and return a 401
gerdziu
gerdziuOP4w ago
But not all of the actions require the actor to be present - for example sign-in/register. So ideally id like to handle that as deep as possible (like in the resource itself).
kernel
kernel4w ago
I thought it's best practice to do that in the router 'these routes need auth' - 'these dont'
kernel
kernel4w ago
i.e:
No description
kernel
kernel4w ago
if you want to do it in the resource then create a custom exception implementation as linked above
kernel
kernel4w ago
No description
gerdziu
gerdziuOP4w ago
I dont want to do that in the router because using the actor in the action is the "source of truth" if this route need auth. I will try to do that with the exceptions you mentioned, thats a nice hint
kernel
kernel4w ago
👍🏿
gerdziu
gerdziuOP4w ago
Ok managed to solve that with custom prepare that raises exception when actor is not present and that custom error page you suggested. Thaks!

Did you find this page helpful?