Dev Series – Phoenix Part 2 – Authentication using Pow
Dev Series – Phoenix Part 2 – Authentication using Pow
Published at June 27, 2021
Last week we have set up our basic application, in this tutorial, I will guide you through setting up user authentication using Pow, a powerful library for user authentication.
ADDING THE PACKAGE
First, let’s add Pow to our dependencies in mix.exs:
{:pow, "~> 1.0"}
Run the following commands to install the dependency:
mix deps.get
After adding the package, let’s install Pow by running the following command. This installs a user schema and migration file that you can use for your basic authentication, registration, and password reset functionality.
mix pow.install
After running the command, you should see the following output:
* creating lib/repz_exercise/users/user.ex
* creating priv/repo/migrations/20210627000000_create_users.ex
Add the following to config/config.exs:
config :repz_exercise, :pow,
user: RepzExercise.Users.User,
repo: RepzExercise.Repo
Remember to update your repository by running migrations:
$ mix ecto.migrate
Once done add the config to your config/config.exs:
config :repz_exercise, :pow,
user: RepzExercise.Users.User,
repo: RepzExercise.Repo
Let’s also run the migration:
mix ecto.migrate
Let’s also add the plug to the browser pipeline:
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_live_flash
plug :put_root_layout, {RepzExerciseWeb.LayoutView, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
plug Pow.Plug.Session, otp_app: :repz_exercise
end
Once done add the routes and configure the protected routes:
defmodule RepzExerciseWeb.Router do
use RepzExerciseWeb, :router
use Pow.Phoenix.Router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_live_flash
plug :put_root_layout, {RepzExerciseWeb.LayoutView, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
plug Pow.Plug.Session, otp_app: :repz_exercise
end
pipeline :api do
plug :accepts, ["json"]
end
pipeline :protected do
plug Pow.Plug.RequireAuthenticated,
error_handler: Pow.Phoenix.PlugErrorHandler
end
scope "/" do
pipe_through :browser
pow_routes()
end
scope "/", RepzExerciseWeb do
pipe_through :browser
get "/", PageController, :index
end
# Other scopes may use custom stacks.
# scope "/api", RepzExerciseWeb do
# pipe_through :api
# end
end
Let’s also add the current user to the connection assigns. Add this to your router:
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_live_flash
plug :put_root_layout, {RepzExerciseWeb.LayoutView, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
plug Pow.Plug.Session, otp_app: :repz_exercise
plug :assign_current_user
end
defp assign_current_user(conn, _opts) do
assign(conn, :current_user, Pow.Plug.current_user(conn))
end
Let’s also add the authentication links to our layout. Update your app.html.eex:
<header>
<section class="container">
<nav role="navigation">
<ul>
<li><a href="https://hexdocs.pm/phoenix/overview.html">Get Started</a></li>
<%= if @current_user do %>
<li>Welcome <%= @current_user.email %></li>
<li><%= link "Sign out", to: Routes.pow_session_path(@conn, :delete), method: :delete %></li>
<% else %>
<li><%= link "Register", to: Routes.pow_registration_path(@conn, :new) %></li>
<li><%= link "Sign in", to: Routes.pow_session_path(@conn, :new) %></li>
<% end %>
</ul>
</nav>
<a href="https://phoenixframework.org/" class="phx-logo">
<img src="<%= Routes.static_path(@conn, "/images/phoenix.png") %>" alt="Phoenix Framework Logo"/>
</a>
</section>
</header>
Let’s start our server and check if everything is working:
mix phx.server
Let’s also add a link to the home page:
<%= link "Home", to: Routes.page_path(@conn, :index) %>
SUMMARY
Great! Now we have set up authentication in our Phoenix. It is painless and straightforward. We can now implement user-specific features like user can only see and edit their own data.
Next week we will implement our first feature.
Cheers and Coding!