LiveView error patterns without redirects

Looking at a lot of the articles out there, as well as the patterns within mix phx.gen.auth, it seems like the go to error for authentication problems is a redirect.

I’m trying to figure out a clean way to handle authorization issues and, in a perfect world, I do it without redirection. So, let’s say someone goofs in the UI and exposes an update page—or even just a button that would expose the update interface—for some resource the user doesn’t currently have access to. (Pretend this user has read only access.) The functions in our context modules handle all the authorization logic so it’s all good in terms of nothing serious happening. The user can’t make an update.

With web apps I am a huge fan of preserving the current URL as much as possible. The reason for this is said user gets annoyed, contacts customer support, and can provide the URL that’s resulting in the error. Redirects… redirect. Pushing someone to a generic “access denied” page isn’t ideal. I’m not sure a flash works in all situation because an error might prevent a resource from getting loaded and result in a template blowing up because some assigns hasn’t been set.

While there are ways around all of these, none are nearly as nice as a dead view app where a plug can check authorization and halt, potentially rendering a completely different template.

Is there a way to handle this sort of pattern in a LiveView without resorting to putting something in every template like if @error do <error partial> else <authorized stuff> end.

1 Like

To me this sound like something you could handle in a Phoenix.LiveView — Phoenix LiveView v0.18.3 hook.

Thanks for pointing this out. I didn’t realize I could invoke hooks without live_session.

With that said, hooks with a {:halt, socket} require a redirect. It’ll raise an exception if you don’t redirect so far as I know.

I’m actually starting get comfortable with the idea of using the main slot in a component like…

<.authorized_view {assigns}>
  ... stuff to display if the user is authorized to see it ...
</.authorized_view>

I think the only way to completely avoid any soft or hard redirect would be to authorize all your context calls and broadcast any changes of permissions to your LV, IMO I would still lean on redirects when it comes to anything auth.

I think I’m just going to record the URL on error and make it available. “Here’s the page you tried to access.”