Current section
Files
Jump to
Current section
Files
templates/controllers/session.ex
defmodule <%= inspect @web_pascal_case %>.Session do
@moduledoc """
Manages user-authenticated sessions.
"""
alias <%= inspect @app_pascal_case %>.Identity
alias <%= inspect @app_pascal_case %>.Identity.User
use <%= inspect @web_pascal_case %>, :controller
def fetch_current_user(conn, _opts) do
with encoded_value when is_binary(encoded_value) <- get_session(conn, :user_token),
{:ok, decoded_value} <- Base.decode64(encoded_value, padding: false),
{:ok, %User{id: user_id}} <- Identity.get_by_token(decoded_value) do
conn
|> put_session(:user_id, user_id)
else
_error ->
conn
|> renew_session()
end
end
def create(conn, %{"value" => value}) do
decoded_value = Base.decode64!(value, padding: false)
case Identity.get_by_token(decoded_value, :session) do
{:ok, %User{id: user_id}} ->
conn
|> put_session(:user_token, value)
|> put_session(:user_id, user_id)
|> put_flash(:info, "Welcome back!")
|> redirect(to: ~p"/")
{:error, _} ->
conn
|> renew_session()
|> put_flash(:error, "Please sign in.")
|> redirect(to: ~p"/sign-in")
end
end
def delete(conn, _params) do
conn
|> get_session("user_id")
|> Identity.delete_all_user_sessions()
conn
|> renew_session()
|> put_flash(:info, "Successfully signed out.")
|> redirect(to: ~p"/")
end
# This function renews the session ID and erases the whole
# session to avoid fixation attacks. If there is any data
# in the session you may want to preserve after log in/log out,
# you must explicitly fetch the session data before clearing
# and then immediately set it after clearing, for example:
#
# defp renew_session(conn) do
# preferred_locale = get_session(conn, :preferred_locale)
#
# conn
# |> configure_session(renew: true)
# |> clear_session()
# |> put_session(:preferred_locale, preferred_locale)
# end
#
defp renew_session(conn) do
delete_csrf_token()
conn
|> configure_session(renew: true)
|> clear_session()
end
end