Hi folks. I have some live views that are access controlled according to the user role in their organization. Right now I use a central access control in the routes definition, and for that I need to a lot of live sessions for each set of permissions. When navigating between them I get whole screen reloads, which is visually bad.
So my question is, do you see a problem in moving this security enforcement to the mount function of each live view and keeping them all in the same live session?
Nope. That’s generally what you do.
Phoenix.LiveView.Router — Phoenix LiveView v1.1.30 and the on_mount option
Just make sure you also do the same checks in the pipe_through. If you don’t you can accidentally do the initial render with privileged data before the on_mount is called (since it hasn’t mounted). Edit: this is wrong. Do it for the other plugs in the same scope though
Also if you need to invalidate their permissions you need to subscribe to something that gets published when permissions change.
phx_gen_auth usually has some stuff included that covers the bits you’d need for authorization and shows a pattern for having 1 module that handles the pipe_through Plug and on_mount socket logic, although if you already have authentication how you like it then just spin up an empty Phoenix app and compare
Edit: to say the on_mount can be set as a list in the router, or a macro call in each liveview module. I’d suggest router so you don’t forget. I wouldn’t generally do it in each and every mount function. I’d use the hook. Then your mount only has to handle its use case and the current user and/or scope is already assigned and authorized
That‘s not correct. mount/3 (and handle_params/3) run on the static render as well. They even need to run to assign all the assigns necessary for render/1. This includes on_mount and all hooks related to those LV callbacks.
Plug based access control only becomes necessary for all the plug pased routes you might have in the same scope of routes.
I don’t know why that has been stuck in my brain for years now.
I think it may have been from telling myself that the forms of reject_unauthorized needed to be used for both, and the wires getting crossed.
I’ll have to re-read all the lifecycle bits to figure out why I was thinking that.
Edit: I legitimately don’t know. I think it was from the bad-old-days of using is_connected? everywhere in the mount, prior to on_mount and having to remind people they couldn’t just rely on the plug bits.