From the Phoenix 1.6.15 docs…
-
{:session, session_config}
- the session information from Plug.Conn
. The session_config
is an exact copy of the arguments given to Plug.Session
. This requires the “_csrf_token” to be given as request parameter with the value of URI.encode_www_form(Plug.CSRFProtection.get_csrf_token())
when connecting to the socket. It can also be a MFA to allow loading config in runtime {MyAppWeb.Auth, :get_session_config, []}
. Otherwise the session will be nil
.
Emphasis:
This requires the “_csrf_token” to be given as request parameter
It looks like _csrf_token
is hardcoded, which doesn’t jive with…
plug :protect_from_forgery, session_key: "_phoenix_sa_csrf_token"
Is there anyway around this?
Context is that dead mount/3
shows proper session, but connected mount/3
doesn’t.
Thanks for the help.
Connected mount does not use plug because it doesn’t go through an HTTP request cycle
Plugs only apply to full HTTP requests which is why you sometimes have “duplicate” functionality in Plugs and Live Hooks
The session shows up properly in both dead and connected mount/3, but only if I don’t use a custom :session_key
in the protect from forgery plug.
plug :protect_from_forgery
Works. Session exists for both unconnected and connected mount/3
.
plug :protect_from_forgery, session_key: "_phoenix_sa_csrf_token"
Breaks LV. I get all those messages in the logs saying to setup my session properly with csrf stuff.
I think because LV is hard coded to use "_csrf_token"
as the session key. From the LV source code:
defp load_csrf_token(endpoint, socket_session) do
if token = socket_session["_csrf_token"] do
state = Plug.CSRFProtection.dump_state_from_session(token)
secret_key_base = endpoint.config(:secret_key_base)
Plug.CSRFProtection.load_state(secret_key_base, state)
end
end
I think Endpoint.socket/3
needs to take an option to specify the session key for the csrf token…
# Router
plug :protect_from_forgery, session_key: "_phoenix_sa_csrf_token"
# Endpoint
socket "/live", Phoenix.LiveView.Socket, websocket: [
connect_info: [
session: [
store: MySessionStore, key: "_my_app_session"
],
csrf_session_key: "_phoenix_sa_csrf_token"
]
]
Something like that.