SkillAgentSearch skills...

Coherence

Coherence is a full featured, configurable authentication system for Phoenix

Install / Use

/learn @smpallen99/Coherence
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Coherence

Build Status Hex Version License

Checkout the Coherence Demo Project to see an example project using Coherence.

Coherence is a full featured, configurable authentication system for Phoenix, with the following modules:

  • Database Authenticatable: handles hashing and storing an encrypted password in the database.
  • Invitable: sends invites to new users with a sign-up link, allowing the user to create their account with their own password.
  • Registerable: allows anonymous users to register a users email address and password.
  • Confirmable: new accounts require clicking a link in a confirmation email.
  • Recoverable: provides a link to generate a password reset link with token expiry.
  • Trackable: saves login statistics like login counts, timestamps, and IP address for each user.
  • Lockable: locks an account when a specified number of failed sign-in attempts has been exceeded.
  • Unlockable With Token: provides a link to send yourself an unlock email.
  • Rememberable: provides persistent login with 'Remember me?' check box on login page.

Coherence provides flexibility by adding namespaced templates and views for only the options specified by the mix coh.install command. This boiler plate code is added to your lib/my_project/web/templates/coherence and lib/my_project/web/views/coherence directories.

Once the boilerplate has been generated, you are free to customize the source as required.

As well, a lib/my_project/web/coherence_web.ex is added. Migrations are also generated to add the required database fields.

See the Docs and Wiki for more information.

Installation

  1. Add coherence to your list of dependencies in mix.exs:

    def deps do
      [{:coherence, "~> 0.8"}]
    end
    
  2. Ensure coherence is started before your application:

    def application do
      extra_applications: [..., :coherence]]
    end
    

Upgrading

After upgrading a Coherence version, you should generate the boilerplate files. To assist this process, use the --reinstall option.

This option uses your project's existing coherence config and runs the the installer with the same options.

mix coh.install --reinstall

Run a git diff to review the updated files. If you had updated any of the boilerplate files, you may need to manually integrate the changes into the newly generated files.

Run mix help coh.install for more information.

Phoenix & Phx Project Structure

Coherence supports projects created with the older mix phoenix.new and the newer mix phx.new commands. Separate versions of the mix tasks exist for each project structure.

For projects created with mix phx.new, use the following mix tasks:

  • coh.install
  • coh.clean

For projects created with mix phx.new --umbrella, ensure you are in the app directory and use the following options for the install:

  • cd apps/my_project
  • coh.install --web-module MyProjectWeb --web-path ../my_project_web/lib/my_project_web

Getting Started

First, decide which modules you would like to use for your project. For the following example we are going to use a full install except for the confirmable option.

Run the installer

$ mix coh.install --full-invitable

This will:

  • add the coherence configuration to the end of your config/config.exs file.
  • add a new User model if one does not already exist
  • add migration files
    • timestamp_add_coherence_to_user.exs if the User model already exists
    • timestamp_create_coherence_user.exs if the User model does not exist
    • timestamp_create_coherence_invitable.exs
  • add view files lib/my_project/web/views/coherence/
  • add template files to lib/my_project/web/templates/coherence
  • add email files to lib/my_project/web/emails/coherence
  • add lib/my_project/web/coherence_web.ex file
  • add lib/my_project/web/coherence_messages.ex file

You should review your config/config.exs as there are a couple items you will need to customize like email address and mail api_key. If you don't edit the email_from value to something different than its default, emails may not be sent.

See Installer for more install options.

You will need to update a few files manually.

# lib/my_project_web/router.ex

defmodule MyProjectWeb.Router do
  use MyProjectWeb, :router
  use Coherence.Router         # Add this

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
    plug Coherence.Authentication.Session  # Add this
  end

  # Add this block
  pipeline :protected do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
    plug Coherence.Authentication.Session, protected: true
  end

  # Add this block
  scope "/" do
    pipe_through :browser
    coherence_routes()
  end

  # Add this block
  scope "/" do
    pipe_through :protected
    coherence_routes :protected
  end

  scope "/", MyProjectWeb do
    pipe_through :browser

    get "/", PageController, :index
    # add public resources below
  end

  scope "/", MyProjectWeb do
    pipe_through :protected

    # add protected resources below
    resources "/privates", MyProjectWeb.PrivateController
  end
end

Important: Note the name-spacing above. Unless you generate coherence controllers, ensure that the scopes, scope "/" do, do not include your projects' scope here. If so, the coherence routes will not work!

If the installer created a user schema (one did not already exist), there is nothing you need to do with that generated file. Otherwise, update your existing schema (assuming its Accounts.User like this:

# lib/my_project/accounts/user.ex

defmodule MyProject.Accounts.User do
  use Ecto.Schema
  use Coherence.Schema                                    # Add this

  schema "users" do
    field :name, :string
    field :email, :string
    coherence_schema()                                    # Add this

    timestamps()
  end

  def changeset(model, params \\ %{}) do
    model
    |> cast(params, [:name, :email] ++ coherence_fields)  # Add this
    |> validate_required([:name, :email])
    |> validate_format(:email, ~r/@/)
    |> validate_coherence(params)                         # Add this
  end

  def changeset(model, params, :password) do
    model
    |> cast(params, ~w(password password_confirmation reset_password_token reset_password_sent_at))
    |> validate_coherence_password_reset(params)
  end
end

An alternative approach is add the authentication plugs to individual controllers that require authentication. You will want to use this approach if you require authentication for a subset of actions in a controller.

For example, lets say you want to show a list of products for everyone visiting the site, but only want authenticated users to be able to create, update, and delete products. You could do the following:

Ensure the following is in your lib/my_project_web/router.ex file:

scope "/", MyProjectWeb do
  pipe_through :browser
  resources "/products", ProductController
end

In your product controller add the following:

defmodule MyProjectWeb.ProductController do
  use MyProjectWeb, :controller

  plug Coherence.Authentication.Session, [protected: true] when action != :index

  # ...
end

Default Configuration

{:require_current_password, true}, # Current password is required when updating new password.
{:reset_token_expire_days, 2},
{:confirmation_token_expire_days, 5},
{:allow_unconfirmed_access_for, 0},
{:max_failed_login_attempts, 5},
{:unlock_timeout_minutes, 20},
{:unlock_token_expire_minutes, 5},
{:rememberable_cookie_expire_hours, 2*24},
{:forwarded_invitation_fields, [:email, :name]}
{:allow_silent_password_recovery_for_unknown_user, false},
{:password_hashing_alg, Comeonin.Bcrypt}

You can override this default configs. For example: you can add the following codes inside config/config.exs

config :coherence,
  require_current_password: false,
  max_failed_login_attempts: 3

Custom registration and sessions routes

Coherence supports custom routes for registration and login. These configurations can be set globally or scoped.

Which routes can be custom?

%{
  registrations_new:  "/registrations/new",
  registrations:      "/registrations",
  passwords:          "/passwords",
  confirmations:      "/confirmations",
  unlocks:            "/unlocks",
  invitations:        "/invitations",
  invitations_create: "/invitations/create",
  invitations_resend: "/invitations/:id/resend",
  sessions:           "/sessions",
  registrations_edit: "/registrations/edit"
}

To set them globally add the following to you configuration:

config :coherence,
  default_routes: %{
    registrations_edit: "/accounts/edit", ...},

To set them scoped for each mode (protected, public, etc..):

scope "/" do
  pipe_through :protected
  coherence_routes :protected, [
    custom_routes: %{registratons_edit: "/accounts/edit", ...}
  ]
end

Phoenix Channel Authentication

Coherence supports channel authentication using Phoenix.Token. To enable channel authentication do the followi

Related Skills

View on GitHub
GitHub Stars1.3k
CategoryDevelopment
Updated1mo ago
Forks221

Languages

Elixir

Security Score

100/100

Audited on Feb 5, 2026

No findings