There was this part in phx.gen.auth
.
defp put_token_in_session(conn, token) do
conn
|> put_session(:user_token, token)
|> put_session(:live_socket_id, "user_sessions:#{Base.url_encode64(token)}")
end
Why Base.url_encoded64
here? So I had just cut it.
- |> put_session(:live_socket_id, "user_sessions:#{Base.url_encode64(token)}")
+ |> put_session(:live_socket_id, token)
After a while, authentication started to malfunction.
Probably because :live_socket_id
is read here?
def log_out_user(conn) do
...
if live_socket_id = get_session(conn, :live_socket_id) do
DemoWeb.Endpoint.broadcast(live_socket_id, "disconnect", %{})
end
...
end
Slowly and painfully, I’ve realised that the value for :live_socket_id
has to be topic
type. and Base.url_encode64
was needed to make it not have multiple colons which confuses the consumer of topic()
. (Let me know if this is even right.)
It was very difficult for me to debug this and understand the use of Base.url_encode64
. Because under the hood, @type topic() :: binary()
. Nothing special. It produces silent bugs. In reality, it has to conform a specific format of topic:subtopic
.
https://hexdocs.pm/phoenix/Phoenix.Socket.html#channel/3
It’s little scary that there is a required format that cannot be a type. Is it really happening? Or am I confused?