Custom Auth

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
@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.
10 Replies
ZachDaniel
ZachDaniel•2y ago
So this is actually a challenge with liveview itself unfortunately you can't update the session like that 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
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
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
Something like that is what we do. 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
frankdugan3•2y ago
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/
Fly
Triggering a Phoenix controller action from a form in a LiveView
Triggering a controller action using phx-trigger-action from a form in a LiveView
frankdugan3
frankdugan3•2y ago
Basically just eliminates the need for a JS hook or whatever.
ZachDaniel
ZachDaniel•2y ago
Yeah, there are problems with that approach too though specifically you either need to 1. validate username/password twice 2. not get "invalid password" errors in your original liveview 3. do ugly stuff w/ flash messages and redirect back to liveview to make it show error messages
frankdugan3
frankdugan3•2y ago
Yeah, that's why I'm just using AshAuthentication/Phoenix. 🙂 Too much complexity to manage myself on every. single. app. lol
ZachDaniel
ZachDaniel•2y ago
sign_in_tokens_enabled? true needs to be in the password section of the resource and if you do that you can sign in directly in the liveview and hit that endpoint w/ the token Agreed @frankdugan3 if you haven't yet, set that sign_in_tokens_enabled? true into your resource in that case just adding that (and updating to latest ash_authentication/ash_authentication_phoenix) will get you a much nicer UI on sign_in errors
samoorai
samooraiOP•2y ago
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? Also I need to customize the text of "Forgot password" "Need Login" because the app is in italian Ok I saw that I can use ovverrides for that, can I also change the links text with them?
frankdugan3
frankdugan3•2y ago
https://github.com/team-alembic/ash_authentication_phoenix/blob/main/lib/ash_authentication_phoenix/overrides/default.ex#L89 Yes: set :reset_toggle_text, "Forgot your password?" I find it's easiest to look at the default overrides file for all the possibilities.
GitHub
ash_authentication_phoenix/default.ex at main · team-alembic/ash_au...
Drop-in authentication support for Phoenix apps using AshAuthentication. - ash_authentication_phoenix/default.ex at main · team-alembic/ash_authentication_phoenix
samoorai
samooraiOP•2y ago
oh I see thanks a lot I can change those texts but I don't see an option for the button text
TechnoMage
TechnoMage•2y ago
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.

Did you find this page helpful?