| I find a lot of engineers I work with don’t understand on_mount. You shouldn’t have duplicate logic in on_mount—if you do, that code should be in a module. You only have the logic once, but you may call the function twice (though you don’t have to). All your auth logic (and any other bits you need to set while starting up request state) should be a function in a module somewhere that returns expected values. Then, you just care to set these values to Conn and Socket assigns appropriately, keeping in mind that Conns and Sockets aren’t the same—when you have one, you don’t have the other. Thus, on_mount to the rescue: 1. Use Plug pipeline(s) to call your module function to compute and add bits to Conn.assigns (and you can add those values to the session to avoid computing again, if you’d like). 2. Use on_mount to assign_new: 2a. assign_new pulls from Conn.assigns by key for the dead render while you have a Conn. 2b. The fallback function gets that value again when you no longer have a Conn (recompute or pull from session if already there). Your actual logic should only exist in one place. And there are easy strategies you can use to avoid expensive computations if necessary. [Edit]: Not suggesting you don’t understand it, just to be clear. I’ve just experienced a lot of coworkers fighting against, abusing, and misunderstanding Conns, Sockets, and assigns. |
Since mix phx.gen.auth handles the authN side, it’s really just authZ that will be idiosyncratic to your application logic.
In every authorization system I’ve written in a Phoenix app (which 8 now), I’ve taken this approach above.
Make a pipeline of rules that take a conn or socket and authorize or not based on what’s in the assigns. Better yet, at the very top of the pipleline, wrap the conn or socket with an auth struct that holds metadata like authorization status and any redirection to be done. Unwrap that struct into the conn or the socket at the end of the pipeline, where the status is resolved.
This way, every request can be default unauthorized and you can apply complex, composable rules for granting permission to take various actions on resources.