-
-
Notifications
You must be signed in to change notification settings - Fork 157
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
POW & LiveView - best way to implement assigns.current_user
?
#706
Comments
Found this gist -> https://dev.to/oliverandrich/how-to-connect-pow-and-live-view-in-your-phoenix-project-1ga1 Really helpful, and answered my questions. But I still think we could have a guide about it in the doc or somewhere. |
The link is
This link gives a 404 now. |
This is how I deal with it at the moment: # TODO: Remove when upstream Pow can handle LiveView/socket auth
defmodule MyAppWeb.Pow.Phoenix.LiveView do
@moduledoc false
use MyAppWeb, :verified_routes
def on_mount(:require_authenticated, _params, session, socket) do
socket = mount_current_user(socket, session)
if socket.assigns.current_user do
{:cont, socket}
else
socket =
socket
|> Phoenix.LiveView.put_flash(:error, "You must be logged in to access this page.")
|> Phoenix.LiveView.redirect(to: ~p"/")
{:halt, socket}
end
end
defp mount_current_user(socket, session) do
Phoenix.Component.assign_new(socket, :current_user, fn ->
pow_config = [otp_app: :my_app_web]
{_conn, user} =
%Plug.Conn{
private: %{
plug_session_fetch: :done,
plug_session: session,
pow_config: pow_config
},
owner: self(),
remote_ip: {0, 0, 0, 0}
}
|> Map.put(:secret_key_base, MyAppWeb.Endpoint.config(:secret_key_base))
|> Pow.Plug.Session.fetch(pow_config)
user
end)
end
end defmodule MyAppWeb.Router do
# ...
scop "/" do
live_session :user_protected, on_mount: [
{MyAppWeb.Pow.Phoenix.LiveView, :require_authenticated}
] do
# ...
end
end
end This is my temporary fix until I get Pow to work out-of-the-box with LiveView. Why it hasn't been done already is due to the million other things I have to tend to. There's a bunch of blockers and caveats to deal with with websockets in Phoenix:
I'm planning to solve three first, to make it safe to use Pow with websockets. This requires a refactor of how session stores currently work. To answer directly the questions for anyone else following:
This is handled on the first load when the request goes through the plug pipeline.
I recommend using the A guide would be good, but this is really something Pow should provide out of the box now that Phoenix LiveView is included in Phoenix 1.7. The guide would need to cover some of the caveats above regarding security (session rotation, etc). If anyone wants to write one let me know, it could go up on https://powauth.com/guides/ along with general recommendations for websocket security. |
Hi @danschultzer , Thanks for your answer. I created a util UserLiveAuth defining an on_mount function to retrieve and then assign the user based on your comment (see code below). And everything works perfectly locally. Sadly, this does not prove to be reliable in production (app and DB hosted on Fly): sometimes everything works, sometimes the function returns nil every other time, and often the user is disconnected for no reason. Here is an example in the monitoring logs, where I constantly update the page, with inconsistent responses:
I tried fetching the current_user in two different ways (see code below), with Do you think this is an error in the architecture of my code? In my way of using POW? Or could this be related to my hosting (Fly.Io)? Thanks for any help, and your work on this library. Source codeUtils module :
First version of get_user :
Second version of get_user , based on your comment :
|
@goulvenclech Looks like you are using the EtsCache. It will reset each time you restart/redeploy (or be fragmented if you are running in a cluster). You should instead use a persistent cache, either Mnesia, Redis, or Postgres as described here: https://github.com/pow-auth/pow#cache-store |
@danschultzer Hum I'm not sure that's the problem... Do you think I didn't configure Mnesia well ? In
In
in
Did I forgot something? |
Oh sorry, I was reading the first version you posted. Yeah it all looks correct. What setup do you have on fly.io? Are you running more than one node at any time? And how do you deal with deployment? That it returns nil every other time, sounds like competing nodes. |
Hi everyone,
What is the standard way to retrieve "current_user" in Liveview using POW?
I'm starting a project from scratch with LiveView and POW, and despite several topics discussing the problem, I can't find any documented solution or tutorial. Even less on recent versions.
My questions:
Pow.Plug.current_user()
orPow.Store.CredentialsCache.get()
? What are the differences, and what is the modern method?conn
, I have to create a plug with aput_session()
function to add the current user ID -> Is there a recommended way to do this? Where should the plug be?assign_new(socket, :current_user, Users.get_user(session["current_user_id"])
in themount()
of each LiveView? Or there's a more practical way to do it?A guide on the subject, particularly in the docs, would be welcome.
Thanks for any help :)
The text was updated successfully, but these errors were encountered: