I’m making a simple passwordless authentication and I use session to persist the current logged in.
In my shared header partial template:
<div id="user-details">
<%= if signed_in?(@conn) do %>
<div id="user">should be the nickname that is stored in the session</div>
<button>Sign Out</button>
<% else %>
<a href="<%= Routes.session_path(@conn, :index) %>">Sign In</a>
<% end %>
</div>
The signed_in? just checks if the :current_user session value is nil or not.
In my session controller I use put_session to store the info to the session.and redirects to home page
def create(conn, %{"user" => %{"nickname" => nickname}}) do
conn
|> put_session(:current_user, nickname)
|> redirect(to: Routes.page_path(conn, :index))
end
My question is how do I access the session directly in the template.
I was able to find the session value through inspect conn
There are multiple options; (if the question is how to access the session ‘directly’)
First, via a helper inside your your_app_web.ex file for the view (should be in the lib folder), it should then exist everywhere where you are rendering a template:
# inside your_app_web.ex file
def view do
quote do
...
# add this function (better to put it in another file and import it here as a helper)
def current_user(conn) do
Plug.Conn.get_session(conn, :current_user)
end
end
end
# Now inside your templates you can use it as:
<%= current_user(@conn) %>
Second, you could also call <%= Plug.Conn.get_session(@conn, :current_user) %> raw inside your template i guess?
Third and last method; you could do is somewhere in the pipeline make a plug that pulls out the wanted session var(s) (with above line) and put it in the conn.assigns, those should then be available in the template with @current_user. This is a bit more implicit because that @current_user will be ‘magically’ be available but it’s not unreasonable to do such a thing for a couple of big ‘global’/often used variables.
It would look like this:
# in your router.ex
defmodule YourAppWeb.Router do
use YourAppWeb, :router
import YourAppWeb.SessionToAssignPlug
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
plug :expose_session_variable_as_assign, :current_user # add this line
end
...
# define this 'plug' somewhere:
defmodule YourAppWeb.SessionToAssignPlug do
import Plug.Conn
def expose_session_variable_as_assign(conn, variable_name) do
session_variable = get_session(conn, variable_name)
assign(conn, variable_name, session_variable)
end
end
# now in your templates you can just do:
<%= @current_user %>