Custom Auth
samoorai:
Hello, I’m trying to get custom auth working but I don’t know how to put the user inside the session after the login form submisison. I created a custom live form with a phx-sumbit event called “save” the method looks like this:
@impl true
def handle_event("save", %{"merchant" => merchant_params}, socket) do
case AshPhoenix.Form.submit(socket.assigns.form, params: merchant_params) do
{:ok, merchant} ->
Logger.error("Loggato con successo")
{:noreply,
socket
|> assign(:current_merchant, merchant)
|> put_flash(:success, "Loggato con successo")
|> push_navigate(to: ~p"/")}
{:error, form} ->
{:noreply, assign(socket, form: form)}
end
end
I was trying to put the logged user inside the socket but I think I’m missing something.
zachdaniel:
So this is actually a challenge with liveview itself unfortunately
zachdaniel:
you can’t update the session like that
zachdaniel:
What we do in the autogenerated stuff is we use a relatively recently added feature to generate a
sign_in_token
and then redirect to a regular controller with that token after sign in
zachdaniel:
case Form.submit(socket.assigns.form,
read_one?: true,
before_submit: fn changeset ->
Ash.Changeset.set_context(changeset, %{token_type: :sign_in})
end
) do
{:ok, user} ->
{:noreply, redirect(socket, to: "/user/password/sign_in_with_token?token=#{user.__metadata__.token}")}
{:error, form} ->
{:noreply,
assign(socket, :form, Form.clear_value(form, :password))}
end
zachdaniel:
Something like that is what we do.
zachdaniel:
So basically to update the session you have to hit a regular controller route (or you need to send something to js and use js to do it, but we’d rather not)
frankdugan3:
There is a decent blog on Fly.io about how to use
phx-trigger-action
to manage the session from a LV. I think this is how the newest version of the phx.auth generator enables LV authentication forms.
https://fly.io/phoenix-files/phx-trigger-action/
frankdugan3:
Basically just eliminates the need for a JS hook or whatever.
zachdaniel:
Yeah, there are problems with that approach too though
zachdaniel:
specifically you either need to
- validate username/password twice
- not get “invalid password” errors in your original liveview
- do ugly stuff w/ flash messages and redirect back to liveview to make it show error messages
frankdugan3:
Yeah, that’s why I’m just using AshAuthentication/Phoenix. 🙂
Too much complexity to manage myself on every. single. app. lol
zachdaniel:
sign_in_tokens_enabled? true
needs to be in the
password
section of the resource
zachdaniel:
and if you do that you can sign in directly in the liveview and hit that endpoint w/ the token
zachdaniel:
Agreed <@433654314175692800>
zachdaniel:
if you haven’t yet, set that
sign_in_tokens_enabled? true
into your resource in that case
zachdaniel:
just adding that (and updating to latest ash_authentication/ash_authentication_phoenix) will get you a much nicer UI on sign_in errors
samoorai:
thanks for the replies. I was using a custom approach to fully customize the ui because I’m using boostrap and not tailwind but actually now I’m back with tailwind. Is there a way to keep the logic of Ash Auth but customizing only the tailwind classes and the ash logo?
samoorai:
Also I need to customize the text of “Forgot password” “Need Login” because the app is in italian
samoorai:
Ok I saw that I can use ovverrides for that, can I also change the links text with them?
frankdugan3:
Yes:
set :reset_toggle_text, "Forgot your password?"
I find it’s easiest to look at the default overrides file for all the possibilities.
samoorai:
oh I see
samoorai:
thanks a lot
samoorai:
I can change those texts but I don’t see an option for the button text
TechnoMage:
I am using a session store that allows updates from liveview FYI. phoenix_livesession. That works, but session updates made from the live view are stored in ETS which has some downsides. It also does pub/sub of session contents which is cool. I will probablly rework it to use regular controller at some point as Ash does.