lud

lud

Ash authentication on mobile

Hello,

I’m trying out the Ash framework for the first time. I am building an API for a mobile app and I want to implement user authentication.

We are in a first-party app and server configuration, so after reading this I’m wondering if the following could be enough:

  • An API endpoint accepting email/password and sending a token
  • An API endpoint using Ash Token features

It’s the first time I’m doing a mobile app so I am not sure. But to me it looks like I do not need to implement OAuth2 or OID Connect.

What do you think?

Thanks!

Marked As Solved

zachdaniel

zachdaniel

Creator of Ash

Correct. You’d want to implement the password strategy. That strategy will add all the actions that you need to your resources. I don’t think that a JSON endpoint is created for you for signing in, but if not it is something you should be able to do with a phoenix controller.

use Phoenix.Controller

def sign_in(conn, %{"username" => username, "password" => password}) do
  YourUserResource
  |> Ash.Query.for_read(:sign_in_with_password, %{username: username, password: password})
  |> YourApi.read_one()
  |> case do
    {:ok, user} ->
      conn |> put_status(200) |> json(%{token: user.__metadata__.token})
   {:error, error} ->
     # handle errors. You should get back an `Ash.Error.Forbidden` 
     # error with a nested error you can use to provide an error message
  end
end

Also Liked

D4no0

D4no0

Usually if there is mobile involved, there is the google/ios authentication involved. They basically send you a JWT token instead of username/password that you can check for validity against their public certificates.

zachdaniel

zachdaniel

Creator of Ash

Got a couple things:

The set_actor plug puts the actor in an idiomatic place on the conn. But it doesn’t call Ash.set_actor/1, that is an “opt-in” tool for storing the actor in the process dictionary.

What I would generally suggest (and will be default in Ash 3.0) is to set this in your api:

authorization do
  authorize :by_default
end

Then authorization will always be running unless you explicitly pass authorize?: false. Not passing an actor is equivalent to actor: nil, but in the default setup, not passing an actor is equivalent to authorize?: false.

If there is a “current actor” then I’d set it as the actor. If its an authentication action, then you can do things like authorize_unless actor_present() to only allow calling it without an actor. You could also add forbid_if always() to make it so that it can only be called with authorize?: false. That is a good way to make something internal only (because api clients and things like that can’t pass authorize?: false.

zachdaniel

zachdaniel

Creator of Ash

Not that you need to, though. You can pretty easily create an endpoint that calls the sign_in_with_password action and extracts the token.

Where Next?

Popular in Questions Top

9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
marick
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I'm a nov...
New

Other popular topics Top

skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
nobody
Hi! In PHP: $SERVER['SERVERADDR'] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement