Coherence
Coherence is a full featured, configurable authentication system for Phoenix
Install / Use
/learn @smpallen99/CoherenceREADME
Coherence
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
-
Add coherence to your list of dependencies in
mix.exs:def deps do [{:coherence, "~> 0.8"}] end -
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.installcoh.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_projectcoh.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.exsfile. - 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
mcp-shrimp-task-manager
2.1kShrimp Task Manager is a task tool built for AI Agents, emphasizing chain-of-thought, reflection, and style consistency. It converts natural language into structured dev tasks with dependency tracking and iterative refinement, enabling agent-like developer behavior in reasoning AI systems.
mcp-shrimp-task-manager
2.1kShrimp Task Manager is a task tool built for AI Agents, emphasizing chain-of-thought, reflection, and style consistency. It converts natural language into structured dev tasks with dependency tracking and iterative refinement, enabling agent-like developer behavior in reasoning AI systems.
contextplus
1.5kSemantic Intelligence for Large-Scale Engineering. Context+ is an MCP server designed for developers who demand 99% accuracy. By combining RAG, Tree-sitter AST, Spectral Clustering, and Obsidian-style linking, Context+ turns a massive codebase into a searchable, hierarchical feature graph.
Peekaboo
2.9kPeekaboo is a macOS CLI & optional MCP server that enables AI agents to capture screenshots of applications, or the entire system, with optional visual question answering through local or remote AI models.
