2026-01-17 · Engineering

Phoenix: Redirect to Requested URL After Authentication

Originally published June 2016 on tensiondriven.github.io


Phoenix offers a few modules for doing authentication, such as passport. One problem I ran into is that I wanted to protect some of my controllers by requiring authentication. If a user visits a url under one of those controllers, I wanted to redirect the user to log in or sign up, and after login (session#create/2) or sign up (registration#create/2), have the user redirected back to the protected page that was originally requested.

To do this, I wrote a Plug and included it in my controllers.

Add custom plug to your project

Create the file require_auth.ex under lib/appname/plugs (you may have to create the directory):

defmodule Checklist.Plugs.RequireAuth do
  import Plug.Conn
  alias Checklist.Router.Helpers

  def init(default), do: default

  def call(conn, _params) do
    case conn.assigns.current_user do
      nil ->
        conn
        |> Plug.Conn.put_session(:redirect_url, conn.request_path)
        |> Phoenix.Controller.put_flash(:info, "Please log in or register to continue.")
        |> Phoenix.Controller.redirect(to: Helpers.registration_path(conn, :new))
      _ ->
        conn
    end
  end
end

Include the plug in the controllers you want to protect

plug Checklist.Plugs.RequireAuth

For example:

defmodule Appname.ChecklistController do
  use Appname.Web, :controller

  plug Appname.Plugs.RequireAuth

  def index(conn, _params) do
    user_id = conn.assigns.current_user.id
    ...

Update registration and session controller to use the stored value

get_session(conn, :redirect_url) || "/" does the magic here — update "/" to be the default url to redirect to after login/signup, if a user logs in or signs up directly.

def create(conn, %{"session" => %{"email" => email, "password" => pass}}) do
  case Session.login(conn, email, pass) do
  {:ok, conn} ->
    path = get_session(conn, :redirect_url) || "/"
    conn
    |> put_flash(:info, "Welcome back!")
    |> redirect(to: path)
    ...

Migrated to Outline January 2026