liveview-native / elixirconf_chat

ElixirConf 2023 Chat App, built with LiveView Native
27 stars 6 forks source link

Persist login state when web app is closed #47

Closed bcardarella closed 10 months ago

bcardarella commented 10 months ago

Steps to reproduce:

  1. visit chat.elixirconf.com
  2. auth into the web app
  3. close tab
  4. new tab visit chat.elixirconf.com

The expectation would be to have you automatically authenticated and in the app but you have to re-auth

bcardarella commented 10 months ago

I'm guessing stuffing the token into localStorage or a cookie would be sufficient

bcardarella commented 10 months ago

This issue doesn't appear to be present in the native apps. I only tested MacOS but I'll assume its the same across the other devices too.

TheFirstAvenger commented 10 months ago

Yes, in native we are storing the token. The issue is that in web we are push-navigating to a url with a token. One of the recurring issues with LiveView is the lack of easy ability to set a cookie or session attribute during a regular LV lifecycle because they need to be set as a response to an http request. You have to manually trigger a deadview load via JS and pass the to-be-stored value back to the server.

The issue in LV

bcardarella commented 10 months ago

@TheFirstAvenger can't we just put the app into a redirect state with that token on first visit? This would force the deadview render and then the app would go into LV state with the token. This is probably something we can just implement in js:

if (var token = localStorage.getItem('token')) {
   window.location = '/chat?token=${token}';
}

and likewise in /chat route we'd just have some js:

var urlParams = new URLSearchParams(window.location.search);
var token = urlParams.get('token');
localStorage.setItem('token', token);
TheFirstAvenger commented 10 months ago

The issue would be if the token was bad somehow (e.g. expired). I will work in some logic to allow the server to tell the browser to clear it in that case, so we don't get stuck in a loop.

supernintendo commented 10 months ago

I think we need branching paths for native and web on this one. put_session/3 is typically used on the web for storing the session token as a cookie but this isn't supported by the Swift platform library so I had to use a custom event to store it in UserDefaults for the native app (link). It's worth revisiting this use case once we dig further into client-side persistence and how to handle that from a LVN app.

bcardarella commented 10 months ago

@TheFirstAvenger if the token is invalid on the redirect it should probably just clear the localStorage token value

TheFirstAvenger commented 10 months ago

@supernintendo The solution I came up with in #54 keys off the same custom event you send from the server to the client to store the token, except the web client stores it in localStorage. If that value exists when you hit the auth page, it sends it to the server to check and redirects if it is valid.