How to manage session state with live view

When reading about live view, I read this from José:

Why would the login be an horrible idea for LiveView?

And, as a more general question, how should session be managed when using LiveView. For regular app, and API endpoints, I usually just have a require_user plug that check the session for a user_id and retrieve the corresponding user from the database. My login action just |> put_session("user_id", user.id) after a successful login.

How would this work with LiveView?

See the original text I was replying to. :slight_smile: If you login through LiveView, then if you navigate to another page or open up another tab, you will have to login again. LiveView keeps the current page state.

When you render a liveview, one of the parameters is the session, which are the session fields currently in your session that you want to send to the liveview.

So if you do:

 live "/foo", FooLiveView, session: [:user_id]

Then the user_id field will also be available in the LiveView mount, which you can retrieve it from the database once again.

So the idea is to login as usual and then pass the relevant session fields to the live view.

5 Likes

Right, I get it, this is what I thought at first, but I wasn’t sure.

So, I can still build my registration page with liveview, but when signing in, I should just use a normal Phoenix page?

Yes. If I understood correctly, LiveView can’t update the :user_id in the session and the LV session is distinct in each browser’s tab.

And two tabs in the same browser won’t sync with each other. Each LiveView session is distinct.

3 Likes

Must have been a late night back in May…sorry I didn’t thank you, but this was very helpful, thanks!

1 Like

Would I be mistaken in thinking that the latest version of LiveView (0.5.0-dev) solves this problem?

0.5.0-dev makes the session available but you still can’t edit it.

2 Likes

Got it, thanks.

If I were set on storing some data about a LV session in the browser session, what would be the best way to do that? Add a vanilla JS link that points to a non-LV controller?

My use-case is that I would like to save some UI state for a returning user even if they don’t login (or have an account).

2 Likes

@tfwright - did you figure this out?

No I never pursued a solution. I’m pretty sure what I suggested above is possible but I’m not really sure it’s best practice.

1 Like

Ok, thanks. I know who my users are so I’ll just write a home-made user state store with updates straight from the liveviews.

i’m confused, we put session with normal redirect to live router? and add session on live router ? that’s it? like

 live "/foo", FooLiveView, session: [:user_id]

it’s oky, but how can update phoenix session in phoenix liveview, becuase I used Oauth2 protocol, and every request I have to send refresh_token and access_token, and update new refresh_token after this. but I’m using Liveview, how can I do? I just can create a normal router which is AuthController but all of my pages are Phoenix liveview

and I have one more question, we have to pass new token every page ? in Liveview ? what about after updating session ?

I realize I’m really /really/ late to the party but I did blog up a solution I put together for login & signup forms in Phoenix LiveView if anyone is still hunting around for options

https://toranbillups.com/blog/archive/2020/06/26/cookie-authentication-with-phoenix-liveview/

8 Likes

And I’ve blogged about storing data in the session in LiveView: https://thepugautomatic.com/2020/05/persistent-session-data-in-phoenix-liveview/

5 Likes

It seems that there is still no consensus pattern to solve the state management with liveview.

1 Like

My solution was to create the login form in a live view, and when the login succeed, I generate a phoenix token and I redirect to /login/:token with a redirect in the live view, /login/:token is a normal controller that check the token and use put_session on the conn as usual.

1 Like

TL;DR: use phx_trigger_action

I’ve came across this thread multiple times past few months while I was looking for a solution, I was about to implement the workaround that people are offering(calling an API to set session) here but I learned about phx_trigger_action attributes for form bindings.

The phx-trigger-action attribute can be added to a form to trigger a standard form submit on DOM patch to the URL specified in the form’s standard action attribute. This is useful to perform pre-final validation of a LiveView form submit before posting to a controller route for operations that require Plug session mutation.

Kudo goes to Pragmatic Studio’s Phoenix LiveView couse. I highly recommend it!

12 Likes

when you use this you have this problem Bug in navigating from a controller to a LiveView page (put_flash message will not be deleted)