Home Posts Post Search Tag Search

Ash Framework 06 - Authentication
Published on: 2025-10-07 Tags: elixir, Blog, Side Project, LiveView, Ecto, Html/CSS, Phoenix, Ash, Framework

Chapter 5: Authentication: Who Are You?

Introducing AshAuthentication

  • Two parts:

    • ash_authentication (core)
    • ash_authentication_phoenix (Phoenix integration)
  • Setup: Install via Igniter:

    mix igniter.install ash_authentication
  • Domain setup:

    • New domain: Tunez.Accounts
    • Resources:
      • Tunez.Accounts.User → for users
      • Tunez.Accounts.Token → for session tokens
    • User DB starts with minimal fields: id and boilerplate configuration
  • Tokens:

    • Handle authentication sessions
    • Configurable, but default works for now
    • Strategy needed for authentication

Setting Up Password Authentication

  • Strategy: email + password (most common)

  • Command:

    mix ash_authentication.add_strategy password
  • Changes applied:

    • email and hashed_password fields added to User
    • Authentication strategy block added
    • Email confirmation add-on
    • Actions for signing in (register_with_password)
    • Modules for email confirmation and password reset
  • Database migration:

    mix ash.migrate
  • Testing in iex:

    • Create a user:

      Ash.Changeset.for_create(:register_with_password, %{email: "...", password: "...", password_confirmation: "..."})
      |> Ash.create!(authorize?: false)
    • Sign in:

      Ash.Query.for_read(:sign_in_with_password, %{email: "...", password: "..."})
      |> Ash.read(authorize?: false)
    • Verify JWT token:

      AshAuthentication.Jwt.verify(user.__metadata__.token, :tunez)
    • Map claims to user:

      AshAuthentication.subject_to_user(claims["sub"], Tunez.Accounts.User)

Automatic UIs with AshAuthenticationPhoenix

  • Install UI integration:

    mix igniter.install ash_authentication_phoenix
  • Generated files:

    • Config: .igniter.exs
    • AuthOverrides → customize look
    • AuthController → handles sign-in requests
    • LiveUserAuth → LiveView hooks
    • Router updates for plugs and routes
  • Tailwind integration:

    @source "../../lib/tunez_web";
    @source "../../deps/ash_authentication_phoenix";
    @plugin "@tailwindcss/forms";
  • LiveView session handling:

    • Routes requiring authentication should be inside ash_authentication_live_session block

    • Example router adjustment:

      ash_authentication_live_session :authenticated_routes do
        live "/", Artists.IndexLive
        live "/albums/:id/edit", Albums.FormLive, :edit
      end

Customizing Components with AuthOverrides

  • Override default classes, text, and behavior for consistent styling

  • Example: submit button styling

    override AshAuthentication.Phoenix.Components.Password.Input do
      set :submit_class, "bg-primary-600 text-white my-4 py-3 px-5 text-sm"
    end
  • Full overrides can be found in auth_overrides_sample.txt


Email Confirmation and Password Reset

  • Handled by SendNewUserConfirmationEmail and SendPasswordResetEmail
  • Uses Phoenix Swoosh for email sending
  • Development emails accessible at: http://localhost:4000/dev/mailbox

Magic Link Authentication

  • Adds “passwordless” login via emailed links

  • Command:

    mix ash_authentication.add_strategy magic_link
    mix ash.migrate
  • Changes:

    • New strategy in Tunez.Accounts.User
    • Actions: sign_in_with_magic_link, request_magic_link
    • Sender module for emails
    • Removes allow_nil?: false for hashed_password

Debugging Authentication

  • Enable verbose logs for development:

    config :ash_authentication, debug_authentication_failures?: true

API Authentication

  • Extend User for JSON API:

    mix ash.extend Tunez.Accounts.User json_api
  • Example route for password registration:

    json_api do
      routes do
        base_route "/users", Tunez.Accounts.User do
          post(:register_with_password, route: "/register")
        end
      end
    end
  • API use restricted to prevent password changes from external calls