AshAuthentication.Phoenix.Router (ash_authentication_phoenix v3.0.0-rc.6)

View Source

Phoenix route generation for AshAuthentication.

Using this module imports the macros in this module and the plug functions from AshAuthentication.Phoenix.Plug.

Usage

Adding authentication to your live-view router is very simple:

defmodule MyAppWeb.Router do
  use MyAppWeb, :router
  use AshAuthentication.Phoenix.Router

  pipeline :browser do
    # ...
    plug(:load_from_session)
  end

  pipeline :api do
    # ...
    plug(:load_from_bearer)
  end

  scope "/", MyAppWeb do
    pipe_through :browser
    sign_in_route auth_routes_prefix: "/auth"
    sign_out_route AuthController
    auth_routes AuthController, MyApp.Accounts.User
    reset_route auth_routes_prefix: "/auth"
  end

Adding Custom Fields to Authentication Forms

You can slot in custom form fields into the authentication forms using the override system.

Step 1: Create a Component for Your Extra Fields

defmodule MyAppWeb.AuthComponents do
  use Phoenix.Component
  import PhoenixHTMLHelpers.Form

  attr :form, :any, required: true

  @spec register_extra(map()) :: Phoenix.LiveView.Rendered.t()
  def register_extra(assigns) do
    ~H"""
    <div>Testing</div>
    """
  end
end

Step 2: Configure Overrides to Use Your Component

defmodule MyAppWeb.AuthOverrides do
  use AshAuthentication.Phoenix.Overrides

  override AshAuthentication.Phoenix.Components.Password do
    set :register_extra_component, &MyAppWeb.AuthComponents.register_extra/1
    set :sign_in_extra_component, &MyAppWeb.AuthComponents.sign_in_extra/1
    set :reset_extra_component, &MyAppWeb.AuthComponents.reset_extra/1
  end
end

Step 3: Pass Overrides to Router Macro

scope "/", MyAppWeb do
  pipe_through :browser
  sign_in_route overrides: [MyAppWeb.AuthOverrides]
end

The component will receive the form as the form assign and will be rendered in the appropriate position within the authentication form.

Summary

Types

Options that can be passed to auth_routes_for.

A list of strategy/add-on names to exclude.

A list of strategy/add-on names to include.

A sub-path if required. Defaults to /auth.

Any options which should be passed to the generated scope.

The controller which will handle success and failure.

Functions

Generates the routes needed for the various strategies for a given AshAuthentication resource.

Generates the routes needed for the various strategies for a given AshAuthentication resource.

Generates a generic, white-label confirmation page using LiveView and the components in AshAuthentication.Phoenix.Components.

Generates a genric, white-label magic link sign in page using LiveView and the components in AshAuthentication.Phoenix.Components.

Generates a recovery code display/generation page using LiveView.

Generates a recovery code verification page for two-factor authentication fallback using LiveView.

Generates a generic, white-label password reset page using LiveView and the components in AshAuthentication.Phoenix.Components. This is the page that allows a user to actually change his password, after requesting a reset token via the sign-in (/reset) route.

Generates a generic, white-label sign-in page using LiveView and the components in AshAuthentication.Phoenix.Components.

Generates a sign-out route with CSRF protection.

Generates a TOTP verification page for two-factor authentication using LiveView.

Generates a TOTP setup page for configuring two-factor authentication using LiveView.

Generates a WebAuthn second-factor verification page using LiveView.

Generates a WebAuthn passkey setup page using LiveView.

Types

auth_route_options()

@type auth_route_options() :: [
  path_option()
  | to_option()
  | scope_opts_option()
  | only_option()
  | except_option()
]

Options that can be passed to auth_routes_for.

except_option()

@type except_option() :: {:except, [atom()]}

A list of strategy/add-on names to exclude.

only_option()

@type only_option() :: {:only, [atom()]}

A list of strategy/add-on names to include.

path_option()

@type path_option() :: {:path, String.t()}

A sub-path if required. Defaults to /auth.

scope_opts_option()

@type scope_opts_option() :: {:scope_opts, keyword()}

Any options which should be passed to the generated scope.

to_option()

@type to_option() :: {:to, AshAuthentication.Phoenix.Controller.t()}

The controller which will handle success and failure.

Functions

auth_routes(auth_controller, resource_or_resources, opts \\ [])

(macro)
@spec auth_routes(
  auth_controller :: module(),
  Ash.Resource.t() | [Ash.Resource.t()],
  auth_route_options()
) :: Macro.t()

Generates the routes needed for the various strategies for a given AshAuthentication resource.

This matches all routes at the provided path, which defaults to /auth. This means that if you have any other routes that begin with /auth, you will need to make sure this appears after them.

Upgrading from auth_routes_for/2

If you are using route helpers anywhere in your application, typically looks like Routes.auth_path/3 or Helpers.auth_path/3 you will need to update them to use verified routes. To see what routes are available to you, use mix ash_authentication.phoenix.routes.

If you are using any of the components provided by AshAuthenticationPhoenix, you will need to supply them with the auth_routes_prefix assign, set to the path you provide here (set to /auth by default).

You also will need to set auth_routes_prefix on the reset_route, i.e reset_route(auth_routes_prefix: "/auth")

Options

  • path - the path to mount auth routes at. Defaults to /auth. If changed, you will also want to change the auth_routes_prefix option in sign_in_route to match. routes.
  • not_found_plug - a plug to call if no route is found. By default, it renders a simple JSON response with a 404 status code.
  • as - the alias to use for the generated scope. Defaults to :auth.
  • only - a list of strategy/add-on names to include. If provided, only routes for strategies and add-ons with names in this list will be generated.
  • except - a list of strategy/add-on names to exclude. If provided, routes for strategies and add-ons with names in this list will not be generated.

auth_routes_for(resource, opts)

(macro)
This macro is deprecated. Replaced by `auth_routes/2..3`. Run `mix igniter.apply_upgrades ash_authentication_phoenix:2.10.5:2.10.6` to fix automatically. .
@spec auth_routes_for(Ash.Resource.t(), auth_route_options()) :: Macro.t()

Generates the routes needed for the various strategies for a given AshAuthentication resource.

This is required if you wish to use authentication.

Options

  • to - a module which implements the AshAuthentication.Phoenix.Controller behaviour. This is required.
  • path - a string (starting with "/") wherein to mount the generated routes.
  • scope_opts - any options to pass to the generated scope.

Example

scope "/", DevWeb do
  auth_routes_for(MyApp.Accounts.User,
    to: AuthController,
    path: "/authentication",
    scope_opts: [host: "auth.example.com"]
  )
end

confirm_route(resource, strategy, opts \\ [])

(macro)
@spec confirm_route(
  resource :: Ash.Resource.t(),
  strategy :: atom(),
  opts :: [
    {:path, String.t()}
    | {:live_view, module()}
    | {:as, atom()}
    | {:overrides, [module()]}
    | {:gettext_fn, {module(), atom()}}
    | {:gettext_backend, {module(), String.t()}}
    | {:on_mount, [module()]}
    | {:on_mount_prepend, [module()]}
    | {atom(), any()}
  ]
) :: Macro.t()

Generates a generic, white-label confirmation page using LiveView and the components in AshAuthentication.Phoenix.Components.

This is used when require_interaction? is set to true on a confirmation strategy.

Available options are:

  • path the path under which to mount the live-view. Defaults to
  • auth_routes_prefix if set, this will be used instead of route helpers when determining routes. Allows disabling helpers: true. If a tuple {:unscoped, path} is provided, the path prefix will not inherit the current route scope. "/<strategy>".
  • token_as_route_param? whether to use the token as a route parameter. i.e <path>/:token. Defaults to true.
  • live_view the name of the live view to render. Defaults to AshAuthentication.Phoenix.ConfirmLive.
  • as which is passed to the generated live route. Defaults to :auth.
  • overrides specify any override modules for customisation. See AshAuthentication.Phoenix.Overrides for more information.
  • gettext_fn as a {module :: module, function :: atom} tuple pointing to a (msgid :: String.t(), bindings :: keyword) :: String.t() typed function that will be called to translate each output text of the live view.
  • gettext_backend as a {module :: module, domain :: String.t()} tuple pointing to a Gettext backend module and specifying the Gettext domain. This is basically a convenience wrapper around gettext_fn.

All other options are passed to the generated scope.

magic_sign_in_route(resource, strategy, opts \\ [])

(macro)
@spec magic_sign_in_route(
  resource :: Ash.Resource.t(),
  strategy :: atom(),
  opts :: [
    {:path, String.t()}
    | {:live_view, module()}
    | {:as, atom()}
    | {:overrides, [module()]}
    | {:gettext_fn, {module(), atom()}}
    | {:gettext_backend, {module(), String.t()}}
    | {:on_mount, [module()]}
    | {:on_mount_prepend, [module()]}
    | {atom(), any()}
  ]
) :: Macro.t()

Generates a genric, white-label magic link sign in page using LiveView and the components in AshAuthentication.Phoenix.Components.

This is used when require_interaction? is set to true on a magic link strategy.

Available options are:

  • path the path under which to mount the live-view. Defaults to
  • auth_routes_prefix if set, this will be used instead of route helpers when determining routes. Allows disabling helpers: true. If a tuple {:unscoped, path} is provided, the path prefix will not inherit the current route scope. "/<strategy>".
  • token_as_route_param? whether to use the token as a route parameter. i.e <path>/:token. Defaults to true.
  • live_view the name of the live view to render. Defaults to AshAuthentication.Phoenix.MagicSignInLive.
  • as which is passed to the generated live route. Defaults to :auth.
  • overrides specify any override modules for customisation. See AshAuthentication.Phoenix.Overrides for more information.
  • gettext_fn as a {module :: module, function :: atom} tuple pointing to a (msgid :: String.t(), bindings :: keyword) :: String.t() typed function that will be called to translate each output text of the live view.
  • gettext_backend as a {module :: module, domain :: String.t()} tuple pointing to a Gettext backend module and specifying the Gettext domain. This is basically a convenience wrapper around gettext_fn.

All other options are passed to the generated scope.

recovery_code_display_route(resource, strategy, opts \\ [])

(macro)

Generates a recovery code display/generation page using LiveView.

This page is used by authenticated users to generate and view their recovery codes. It should be placed behind authentication middleware.

Available options are:

  • path the path under which to mount the live-view. Defaults to /recovery-codes.
  • auth_routes_prefix if set, this will be used instead of route helpers when determining routes.
  • live_view the name of the live view to render. Defaults to AshAuthentication.Phoenix.RecoveryCodeDisplayLive.
  • as which is passed to the generated live route. Defaults to :auth.
  • overrides specify any override modules for customisation.
  • gettext_fn as a {module :: module, function :: atom} tuple.
  • gettext_backend as a {module :: module, domain :: String.t()} tuple.

All other options are passed to the generated scope.

Example

scope "/", MyAppWeb do
  pipe_through [:browser, :require_authenticated_user]
  recovery_code_display_route MyApp.Accounts.User, :recovery_code, auth_routes_prefix: "/auth"
end

recovery_code_verify_route(resource, strategy, opts \\ [])

(macro)

Generates a recovery code verification page for two-factor authentication fallback using LiveView.

This page is used when a user needs to authenticate with a recovery code instead of their TOTP authenticator. It supports both token-based flow (after password sign-in) and step-up authentication (re-verify for protected resources).

Available options are:

  • path the path under which to mount the live-view. Defaults to /recovery-code-verify.
  • auth_routes_prefix if set, this will be used instead of route helpers when determining routes. Allows disabling helpers: true. If a tuple {:unscoped, path} is provided, the path prefix will not inherit the current route scope.
  • live_view the name of the live view to render. Defaults to AshAuthentication.Phoenix.RecoveryCodeVerifyLive.
  • as which is passed to the generated live route. Defaults to :auth.
  • overrides specify any override modules for customisation. See AshAuthentication.Phoenix.Overrides for more information.
  • gettext_fn as a {module :: module, function :: atom} tuple pointing to a (msgid :: String.t(), bindings :: keyword) :: String.t() typed function that will be called to translate each output text of the live view.
  • gettext_backend as a {module :: module, domain :: String.t()} tuple pointing to a Gettext backend module and specifying the Gettext domain.

All other options are passed to the generated scope.

Example

scope "/", MyAppWeb do
  pipe_through :browser
  recovery_code_verify_route MyApp.Accounts.User, :recovery_code, auth_routes_prefix: "/auth"
end

reset_route(opts \\ [])

(macro)
@spec reset_route(
  opts :: [
    {:path, String.t()}
    | {:live_view, module()}
    | {:as, atom()}
    | {:overrides, [module()]}
    | {:gettext_fn, {module(), atom()}}
    | {:gettext_backend, {module(), String.t()}}
    | {:on_mount, [module()]}
    | {:on_mount_prepend, [module()]}
    | {atom(), any()}
  ]
) :: Macro.t()

Generates a generic, white-label password reset page using LiveView and the components in AshAuthentication.Phoenix.Components. This is the page that allows a user to actually change his password, after requesting a reset token via the sign-in (/reset) route.

Available options are:

  • path the path under which to mount the live-view. Defaults to /password-reset.
  • auth_routes_prefix if set, this will be used instead of route helpers when determining routes. Allows disabling helpers: true. If a tuple {:unscoped, path} is provided, the path prefix will not inherit the current route scope.
  • live_view the name of the live view to render. Defaults to AshAuthentication.Phoenix.ResetLive.
  • as which is passed to the generated live route. Defaults to :auth.
  • overrides specify any override modules for customisation. See AshAuthentication.Phoenix.Overrides for more information.
  • gettext_fn as a {module :: module, function :: atom} tuple pointing to a (msgid :: String.t(), bindings :: keyword) :: String.t() typed function that will be called to translate each output text of the live view.
  • gettext_backend as a {module :: module, domain :: String.t()} tuple pointing to a Gettext backend module and specifying the Gettext domain. This is basically a convenience wrapper around gettext_fn.
  • resources - Which resources should have their sign in UIs rendered. Defaults to all resources that use AshAuthentication.

All other options are passed to the generated scope.

sign_in_route(opts \\ [])

(macro)
@spec sign_in_route(
  opts :: [
    {:path, String.t()}
    | {:live_view, module()}
    | {:as, atom()}
    | {:on_mount, [module()]}
    | {:overrides, [module()]}
    | {:gettext_fn, {module(), atom()}}
    | {:gettext_backend, {module(), String.t()}}
    | {:on_mount_prepend, [module()]}
    | {atom(), any()}
  ]
) :: Macro.t()

Generates a generic, white-label sign-in page using LiveView and the components in AshAuthentication.Phoenix.Components.

This is completely optional.

Available options are:

  • path the path under which to mount the sign-in live-view. Defaults to /sign-in within the current router scope.
  • auth_routes_prefix if set, this will be used instead of route helpers when determining routes. Allows disabling helpers: true. If a tuple {:unscoped, path} is provided, the path prefix will not inherit the current route scope.
  • register_path - the path under which to mount the password strategy's registration live-view. If not set, no registration route will be generated. The registration form will still be accessible via a toggle on the sign-in page (switching forms with JavaScript rather than navigation). To fully disable registration, either set registration_enabled? false on the password strategy in your resource (see AshAuthentication.Strategy.Password), or hide the toggle by setting register_toggle_text: nil in your overrides (see AshAuthentication.Phoenix.Overrides). If a tuple {:unscoped, path} is provided, the registration path will not inherit the current route scope.
  • reset_path - the path under which to mount the password strategy's password reset live-view, for a user to request a reset token by email. If not set, no reset route will be generated. The reset form will still be accessible via a toggle on the sign-in page (switching forms with JavaScript rather than navigation). To hide the toggle, set reset_toggle_text: nil in your overrides (see AshAuthentication.Phoenix.Overrides). If a tuple {:unscoped, path} is provided, the reset path will not inherit the current route scope.
  • resources - Which resources should have their sign in UIs rendered. Defaults to all resources that use AshAuthentication.
  • live_view the name of the live view to render. Defaults to AshAuthentication.Phoenix.SignInLive.
  • as which is used to prefix the generated live_session and live route name. Defaults to :auth.
  • otp_app the otp app or apps to find authentication resources in. Pulls from the socket by default.
  • overrides specify any override modules for customisation. See AshAuthentication.Phoenix.Overrides for more information.
  • gettext_fn as a {module :: module, function :: atom} tuple pointing to a (msgid :: String.t(), bindings :: keyword) :: String.t() typed function that will be called to translate each output text of the live view.
  • gettext_backend as a {module :: module, domain :: String.t()} tuple pointing to a Gettext backend module and specifying the Gettext domain. This is basically a convenience wrapper around gettext_fn.
  • on_mount_prepend - Same as on_mount, but for hooks that need to be run before AshAuthenticationPhoenix's hooks.

All other options are passed to the generated scope.

sign_out_route(auth_controller, path \\ "/sign-out", opts \\ [])

(macro)
@spec sign_out_route(AshAuthentication.Phoenix.Controller.t(), path :: String.t(), [
  {:as, atom()}
  | {:live_view, module()}
  | {:otp_app, atom()}
  | {:overrides, [module()]}
  | {:layout, {module(), atom()} | false}
  | {:on_mount, [module()]}
  | {:on_mount_prepend, [module()]}
  | {:gettext_fn, {module(), atom()}}
  | {:gettext_backend, {module(), String.t()}}
  | {atom(), any()}
]) :: Macro.t()

Generates a sign-out route with CSRF protection.

This generates two routes:

  • A GET route that renders a sign-out confirmation page using LiveView. The page displays a form with a button that submits a DELETE request.
  • A DELETE route that points to the sign_out action in your auth controller.

This two-step approach prevents logout CSRF attacks, where a malicious site could force users to sign out by embedding a link to the sign-out URL.

Options

  • path - the path to mount the sign-out routes at. Defaults to /sign-out.
  • live_view - the LiveView module to use for the confirmation page. Defaults to AshAuthentication.Phoenix.SignOutLive.
  • as - the alias for the generated routes. Defaults to :auth.
  • otp_app - the OTP app to find authenticated resources in.
  • overrides - override modules for customisation. See AshAuthentication.Phoenix.Overrides for more information.
  • layout - the layout to use for the LiveView.
  • on_mount - additional on_mount hooks for the live session.
  • on_mount_prepend - hooks to run before the default hooks.
  • gettext_fn - a {module, function} tuple for text translation.
  • gettext_backend - a {module, domain} tuple for Gettext.

All other options are passed to the generated scope.

totp_2fa_route(resource, strategy, opts \\ [])

(macro)
@spec totp_2fa_route(
  resource :: Ash.Resource.t(),
  strategy :: atom(),
  opts :: [
    {:path, String.t()}
    | {:live_view, module()}
    | {:as, atom()}
    | {:overrides, [module()]}
    | {:gettext_fn, {module(), atom()}}
    | {:gettext_backend, {module(), String.t()}}
    | {:on_mount, [module()]}
    | {:on_mount_prepend, [module()]}
    | {atom(), any()}
  ]
) :: Macro.t()

Generates a TOTP verification page for two-factor authentication using LiveView.

This page is used after primary authentication (e.g., password sign-in) when the user has TOTP enabled. It displays a form for entering the TOTP code.

Available options are:

  • path the path under which to mount the live-view. Defaults to /totp-verify.
  • auth_routes_prefix if set, this will be used instead of route helpers when determining routes. Allows disabling helpers: true. If a tuple {:unscoped, path} is provided, the path prefix will not inherit the current route scope.
  • live_view the name of the live view to render. Defaults to AshAuthentication.Phoenix.TotpVerifyLive.
  • as which is passed to the generated live route. Defaults to :auth.
  • overrides specify any override modules for customisation. See AshAuthentication.Phoenix.Overrides for more information.
  • gettext_fn as a {module :: module, function :: atom} tuple pointing to a (msgid :: String.t(), bindings :: keyword) :: String.t() typed function that will be called to translate each output text of the live view.
  • gettext_backend as a {module :: module, domain :: String.t()} tuple pointing to a Gettext backend module and specifying the Gettext domain. This is basically a convenience wrapper around gettext_fn.

All other options are passed to the generated scope.

Example

scope "/", MyAppWeb do
  pipe_through :browser
  totp_2fa_route MyApp.Accounts.User, :totp, auth_routes_prefix: "/auth"
end

totp_setup_route(resource, strategy, opts \\ [])

(macro)
@spec totp_setup_route(
  resource :: Ash.Resource.t(),
  strategy :: atom(),
  opts :: [
    {:path, String.t()}
    | {:live_view, module()}
    | {:as, atom()}
    | {:overrides, [module()]}
    | {:gettext_fn, {module(), atom()}}
    | {:gettext_backend, {module(), String.t()}}
    | {:on_mount, [module()]}
    | {:on_mount_prepend, [module()]}
    | {atom(), any()}
  ]
) :: Macro.t()

Generates a TOTP setup page for configuring two-factor authentication using LiveView.

This page is used by authenticated users to set up TOTP on their account. It displays a QR code that can be scanned with an authenticator app, and a code input field to confirm the setup.

Important: This route should be protected by authentication middleware to ensure only authenticated users can access it.

Available options are:

  • path the path under which to mount the live-view. Defaults to /totp-setup.
  • auth_routes_prefix if set, this will be used instead of route helpers when determining routes. Allows disabling helpers: true. If a tuple {:unscoped, path} is provided, the path prefix will not inherit the current route scope.
  • live_view the name of the live view to render. Defaults to AshAuthentication.Phoenix.TotpSetupLive.
  • as which is passed to the generated live route. Defaults to :auth.
  • overrides specify any override modules for customisation. See AshAuthentication.Phoenix.Overrides for more information.
  • gettext_fn as a {module :: module, function :: atom} tuple pointing to a (msgid :: String.t(), bindings :: keyword) :: String.t() typed function that will be called to translate each output text of the live view.
  • gettext_backend as a {module :: module, domain :: String.t()} tuple pointing to a Gettext backend module and specifying the Gettext domain. This is basically a convenience wrapper around gettext_fn.

All other options are passed to the generated scope.

Example

scope "/", MyAppWeb do
  pipe_through [:browser, :require_authenticated_user]
  totp_setup_route MyApp.Accounts.User, :totp, auth_routes_prefix: "/auth"
end

webauthn_2fa_route(resource, strategy, opts \\ [])

(macro)
@spec webauthn_2fa_route(
  resource :: Ash.Resource.t(),
  strategy :: atom(),
  opts :: [
    {:path, String.t()}
    | {:live_view, module()}
    | {:as, atom()}
    | {:overrides, [module()]}
    | {:gettext_fn, {module(), atom()}}
    | {:gettext_backend, {module(), String.t()}}
    | {:on_mount, [module()]}
    | {:on_mount_prepend, [module()]}
    | {atom(), any()}
  ]
) :: Macro.t()

Generates a WebAuthn second-factor verification page using LiveView.

Mirrors totp_2fa_route/3 but for the WebAuthn strategy. Mounts AshAuthentication.Phoenix.WebAuthnVerifyLive and offers two flows:

  • /<path>/:token — token flow, used after a primary sign-in.
  • /<path> — step-up flow, used by an already-signed-in user.

Options

  • path — the path under which to mount. Defaults to /webauthn-verify.
  • auth_routes_prefix — required, makes the form action URLs work.
  • live_view — defaults to AshAuthentication.Phoenix.WebAuthnVerifyLive.
  • as — passed to the generated live route. Defaults to :auth.
  • overrides, on_mount, on_mount_prepend, gettext_fn, gettext_backend, layout — same as totp_2fa_route/3.

Example

scope "/", MyAppWeb do
  pipe_through :browser
  webauthn_2fa_route MyApp.Accounts.User, :webauthn, auth_routes_prefix: "/auth"
end

webauthn_setup_route(resource, strategy, opts \\ [])

(macro)
@spec webauthn_setup_route(
  resource :: Ash.Resource.t(),
  strategy :: atom(),
  opts :: [
    {:path, String.t()}
    | {:live_view, module()}
    | {:as, atom()}
    | {:overrides, [module()]}
    | {:gettext_fn, {module(), atom()}}
    | {:gettext_backend, {module(), String.t()}}
    | {:on_mount, [module()]}
    | {:on_mount_prepend, [module()]}
    | {atom(), any()}
  ]
) :: Macro.t()

Generates a WebAuthn passkey setup page using LiveView.

Mirrors totp_setup_route/3. Mounts AshAuthentication.Phoenix.WebAuthnSetupLive (which wraps ManageCredentials) so authenticated users can register, label, or revoke passkeys.

Pair with your authenticated-user pipeline so only signed-in users hit it.

Options

  • path — defaults to /webauthn-setup.
  • auth_routes_prefix — required.
  • live_view, as, overrides, etc. — see totp_setup_route/3.