Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making conn.assigns available in multiple Phoenix views/templates

I need a user authentication token defined in the SessionControllerto be available in layout/app.html.eex.

My SessionController defines a token and assigns it to a conn.

token = Phoenix.Token.sign(conn, "user socket", user)

assign(conn, :user_token, token)

Then when I try to use the token in app.html.eex like the following,

 <script>window.userToken = "<%= assigns[:user_token] %>"</script>

or

 <script>window.userToken = "<%= @user_token %>"</script>

I get this error: (ArgumentError) assign @user_token not available in eex template.

like image 525
Jason O. Avatar asked Dec 10 '16 08:12

Jason O.


1 Answers

conn.assigns are reset on every request. If you want to store something in SessionController and have it available in future requests, you can use put_session;

In your SessionController:

token = Phoenix.Token.sign(conn, "user socket", user)
conn
|> put_session(:user_token, token)
|> render(...)

Then, to access it in other controllers, you can use:

token = get_session(conn, :user_token)

To access it in multiple templates, you can then add a plug to the appropriate pipeline(s) in your Router:

pipeline :browser do
  ...
  plug :fetch_user_token
end

...

def fetch_user_token(conn, _) do
  conn
  |> assign(:user_token, get_session(conn, :user_token))
end

Now you can access the token in any template with @user_token (or assigns[:user_token] or assigns.user_token or @conn.assigns[:user_token] or @conn.assigns.user_token; all will give the same result here).

like image 51
Dogbert Avatar answered Nov 09 '22 22:11

Dogbert