authority v0.1.0 Authority.Authentication behaviour

A behaviour for authenticating users.

Usage

Authentication happens in stages in the following order, each with a callback:

  • before_identify/1
  • identify/1
  • before_validate/2
  • validate/3
  • after_validate/2
  • failed/2

First, define your module:

defmodule MyApp.Accounts.Authentication do
  use Authority.Authentication

  # OPTIONAL
  @impl Authority.Authentication
  def before_identify(identifier) do
    # Do anything you need to do to the identifier
    # before it is used to identify the user
  end

  # REQUIRED
  @impl Authority.Authentication
  def identify(identifier) do
    # Identify the user
  end

  # OPTIONAL
  @impl Authority.Authentication
  def before_validate(user, purpose) do
    # Define any additional checks that should determine
    # if authentication is permitted.
    #
    # For example, check if the user is active or if the
    # account is locked.
  end

  # REQUIRED
  @impl Authority.Authentication
  def validate(credential, user, purpose) do
    # check if the credential is valid for the user
  end

  # OPTIONAL
  @impl Authority.Authentication
  def after_validate(user, purpose) do
    # Clean up after a successful authentication
  end

  # OPTIONAL
  @impl Authority.Authentication
  def failed(user, error) do
    # Do anything that needs to be done on failure, such as
    # locking the user account on too many failed attempts
  end
end

Second, call the authenticate/2 function:

MyApp.Accounts.Authentication.authenticate({email, password})

# Specify a purpose, the default is `:any`
MyApp.Accounts.Authentication.authenticate({email, password}, :recovery)

This will use all the callbacks defined and described above.

Link to this section Summary

Types

A credential for a user, such as an email/password pair, or a token

An authentication error

An identifier for a user

The purpose for the authentication request. This can be used as the basis to approve or deny the request. Defaults to :any

An authenticated user. Can be any type that represents a user in your system

Callbacks

This function will be called after validate/2, if validation was successful. Use it to clean up after a successful authentication

Converts a credential into a user. Assumes the purpose :any

Converts a credential into a user, provided that the credential is valid for the given purpose

This function will be called before identify/1. Use it to modify or refresh the identifier before it is used to lookup the user

This function will be called before validate/2. Use it to add additional checks, such as whether the user is active or locked

This function will be called if the authentication attempt fails for any reason. Use it to apply security locks or anything else that needs to be done on failure

Identifies the user from the given identifier

Validates whether the given credential is valid for the identified user and purpose

Link to this section Types

Link to this type credential()
credential() :: {id(), any()} | any()

A credential for a user, such as an email/password pair, or a token.

When a tuple, the first element is an identifier (like an email), which will be used to lookup the user. The second element is the credential.

When not a tuple, (like a token) the credential will also be used for both purposes, to identify the user and validate the request.

Link to this type error()
error() :: {:error, term()}

An authentication error.

Link to this type id()
id() :: any()

An identifier for a user.

Link to this type purpose()
purpose() :: atom()

The purpose for the authentication request. This can be used as the basis to approve or deny the request. Defaults to :any.

Link to this type user()
user() :: any()

An authenticated user. Can be any type that represents a user in your system.

Link to this section Callbacks

Link to this callback after_validate(user, purpose)
after_validate(user(), purpose()) :: :ok | error()

This function will be called after validate/2, if validation was successful. Use it to clean up after a successful authentication.

Link to this callback authenticate(credential)
authenticate(credential()) :: :ok | error()

Converts a credential into a user. Assumes the purpose :any.

Link to this callback authenticate(credential, purpose)
authenticate(credential(), purpose()) :: :ok | error()

Converts a credential into a user, provided that the credential is valid for the given purpose.

Link to this callback before_identify(id)
before_identify(id()) :: {:ok, id()} | error()

This function will be called before identify/1. Use it to modify or refresh the identifier before it is used to lookup the user.

Link to this callback before_validate(user, purpose)
before_validate(user(), purpose()) :: :ok | error()

This function will be called before validate/2. Use it to add additional checks, such as whether the user is active or locked.

Link to this callback failed(user, error)
failed(user(), error()) :: :ok | error()

This function will be called if the authentication attempt fails for any reason. Use it to apply security locks or anything else that needs to be done on failure.

Link to this callback identify(id)
identify(id()) :: {:ok, user()} | error()

Identifies the user from the given identifier.

Link to this callback validate(credential, user, purpose)
validate(credential(), user(), purpose()) :: :ok | error()

Validates whether the given credential is valid for the identified user and purpose.