SkillAgentSearch skills...

Pow

Robust, modular, and extendable user authentication system

Install / Use

/learn @pow-auth/Pow
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Pow

Github CI hexdocs.pm hex.pm

Pow is a robust, modular, and extendable authentication and user management solution for Phoenix and Plug-based apps.

Features

Installation

Add Pow to your list of dependencies in mix.exs:

defp deps do
  [
    # ...
    {:pow, "~> 1.0.39"}
  ]
end

Run mix deps.get to install it.

Getting started

Phoenix app

Umbrella project: Check out the umbrella project guide.

Install the necessary files:

mix pow.install

This will add the following files to your app:

LIB_PATH/users/user.ex
PRIV_PATH/repo/migrations/TIMESTAMP_create_users.ex

And also update the following files:

config/config.exs
WEB_PATH/endpoint.ex
WEB_PATH/router.ex

Run migrations with mix setup, start the server with mix phx.server, and you can now visit http://localhost:4000/registration/new to create a user.

Modify templates

By default, Pow exposes as few files as possible.

If you wish to modify the templates, you can generate them using:

mix pow.phoenix.gen.templates

This will also add web_module: MyAppWeb to the configuration in config/config.exs.

Extensions

Pow is made so it's easy to extend the functionality with your own complimentary library. The following extensions are included in this library:

Check out the "Other libraries" section for other extensions.

Add extensions support

To keep it easy to understand and configure Pow, you'll have to enable the extensions yourself.

Let's install the PowResetPassword and PowEmailConfirmation extensions.

First, install extension migrations by running:

mix pow.extension.ecto.gen.migrations --extension PowResetPassword --extension PowEmailConfirmation

Then run the migrations with mix ecto.migrate. Now, update config/config.ex with the :extensions and :controller_callbacks key:

config :my_app, :pow,
  user: MyApp.Users.User,
  repo: MyApp.Repo,
  extensions: [PowResetPassword, PowEmailConfirmation],
  controller_callbacks: Pow.Extension.Phoenix.ControllerCallbacks

Update LIB_PATH/users/user.ex with the extensions:

defmodule MyApp.Users.User do
  use Ecto.Schema
  use Pow.Ecto.Schema
  use Pow.Extension.Ecto.Schema,
    extensions: [PowResetPassword, PowEmailConfirmation]

  # ...

  def changeset(user_or_changeset, attrs) do
    user_or_changeset
    |> pow_changeset(attrs)
    |> pow_extension_changeset(attrs)
  end
end

Add Pow extension routes to WEB_PATH/router.ex:

defmodule MyAppWeb.Router do
  use MyAppWeb, :router
  use Pow.Phoenix.Router
  use Pow.Extension.Phoenix.Router,
    extensions: [PowResetPassword, PowEmailConfirmation]

  # ...

  scope "/" do
    pipe_through :browser

    pow_routes()
    pow_extension_routes()
  end

  # ...
end

Modify extension templates

Templates for extensions can be generated with:

mix pow.extension.phoenix.gen.templates --extension PowResetPassword --extension PowEmailConfirmation

Please follow the instructions in "Modify templates" to ensure that your custom templates will be used.

Mailer support

Many extensions require a mailer to have been set up. Let's create a mailer mock module in WEB_PATH/mails/pow/mailer.ex:

defmodule MyAppWeb.Pow.Mailer do
  use Pow.Phoenix.Mailer
  require Logger

  def cast(%{user: user, subject: subject, text: text, html: html, assigns: _assigns}) do
    # Build email struct to be used in `process/1`

    %{to: user.email, subject: subject, text: text, html: html}
  end

  def process(email) do
    # Send email

    Logger.debug("E-mail sent: #{inspect email}")
  end
end

Update config/config.ex with :mailer_backend key:

config :my_app, :pow,
  # ...
  mailer_backend: MyAppWeb.Pow.Mailer

This mailer module will only output the mail to your log, so you can e.g. try out the reset password and email confirmation links. You should integrate the Pow mailer with your actual mailer system. For Swoosh or Bamboo integration, check out the Configuring mailer guide.

Modify mailer templates

Generate the template files:

mix pow.extension.phoenix.mailer.gen.templates --extension PowResetPassword --extension PowEmailConfirmation

This will generate template files in the WEB_PATH/mails/ directory. This will also add the necessary mail/0 macro to WEB_PATH/my_app_web.ex and update the pow config with web_mailer_module: MyAppWeb.

Configuration

Pow is built to be modular, and easy to configure. The configuration is passed to function calls as well as plug options, and they will take priority over any environment configuration. It's ideal in case you got an umbrella app with multiple separate user domains.

The easiest way to use Pow with Phoenix is to use a :otp_app in function calls and set the app environment configuration. It will keep a persistent fallback configuration that you configure in one place.

Module groups

Pow has three main groups of modules that each can be used individually, or in conjunction with each other:

Pow.Plug

This group will handle the plug connection. The configuration will be assigned to conn.private[:pow_config] and passed through the controller to the users' context module. The Plug module has functions to authenticate, create, update, and delete users, and will generate/renew the session automatically.

Pow.Ecto

This group contains all modules related to the Ecto based user schema and context. By default, Pow will use the Pow.Ecto.Context module to authenticate, create, update and delete users with lookups to the database. However, it's straightforward to extend or write your custom user context. You can do this by setting the :users_context configuration key.

Pow.Phoenix

This group contains the controllers and templates for Phoenix. You only need to set the (session) plug in endpoint.ex and add the routes to router.ex. Templates are not generated by default, instead, the compiled templates in Pow are used. You can generate the templates used by running mix pow.phoenix.gen.templates. You can also customize flash messages and callback routes by creating your own using :messages_backend and :routes_backend.

The registration and session controllers can be changed with your customized versions too, but since the routes are built on compile time, you'll have to set them up in router.ex with :pow namespace. For minor pre/post-processing of requests, you can use the :controller_callbacks option. It exists to make it easier to modify flow with extensions (e.g., send a confirmation email upon user registration).

Pow.Extension

This module helps build extensions for Pow. There're three extension mix tasks to generate Ecto migrations and phoenix templates.

mix pow.extension.ecto.gen.migrations
mix pow.extension.phoenix.gen.templates
mix pow.extension.phoenix.mailer.gen.templates

Authorization plug

Pow ships with a session plug module. You can easily switch it out with a different one. As an example, here's how you do that with Phoenix.Token:

defmodule MyAppWeb.Pow.Plug do
  use Pow.Plug.Base

  @session_key :pow_user_token
  @salt "user salt"
  @max_age 86400

  def fetch(conn, config) do
    conn  = Plug.Conn.fetch_session(conn)
    token = Plug.Conn.get_session(conn, @session_key)

    MyAppWeb.Endpoint
    |> Phoenix.Token.verify(@salt, token, max_age: @max_age)
    |> maybe_load_user(conn)
  end

  defp maybe_load_user({:ok, user_id}, conn), do: {conn, MyApp.Repo.get(User, user_id)}
  defp maybe_load_user({:error, _any}, conn), do: {conn, nil}

  def create(conn, user, config) do
    token = Phoenix.Token.sign(MyAppWeb.Endpoint, @salt, user.id)
    conn  =
      conn
      |> Plug.Conn.fetch_session()
      |> Plug.Conn.put_session(@session_key, token)

    {conn, user}
  end

  def delete(conn, config) do
    conn
    |> Plug.Conn.fetch_session()
    |> Plug.Conn.delete_session(@session_key)
  end
end

defmodule MyAppWeb.Endpoint do
  # ...

  plug MyAppWeb.Pow.Plug, otp_app: :my_app
end

Ecto changeset

The user module has a fallback changeset/2 function. If you want to add custom validations, you can use the pow_changeset/2 function like so:

defmodule MyApp.Users.User do
  use Ecto.Schema
  use Pow.Ecto.Schema

  schema "users" do
    field :custom, :string

    pow_user_fields()

    timestamps()
  end

  def changeset(user_or_changeset, attrs) do
    user_or_changeset
    |> pow_changeset(attrs)
    |> Ecto.Changeset.cast(attrs, [:custom])
    |> Ecto.Changeset.validate_required([:custom])
  end
end

Phoenix controllers

Controllers in Pow are very slim and consists of just one Pow.Plug function call with response functions. If you wish to change the flow of the Pow.Phoenix.RegistrationController and Pow.Phoenix.SessionController, the best w

View on GitHub
GitHub Stars1.7k
CategoryDevelopment
Updated14h ago
Forks161

Languages

Elixir

Security Score

100/100

Audited on Apr 9, 2026

No findings