I’m building a multi-tenant SaaS application with Django Ninja as the backend and Next.js as the frontend. I’m running into a problem around handling RBAC permissions and org-level feature entitlements without causing bad UI behaviour.
For RBAC, I first tried fetching permissions/features from an API after login. But in Next.js, this caused a UX issue:
To avoid this for RBAC, I moved the permissions into the JWT, so the frontend can instantly check them at page load. This works well, but I’m unsure if I should do the same for feature entitlements (since those are org-level and can change dynamically).
tldr: use SSR.
This may not be the cleanest solution, but at least it should work.
I assume that at some point you will eventually load the user from the backend, to display name, avatar, etc. So why not preload it on the backend (NextJS) during the SSR phase, so requests can be cached, UI will be prerendered, no need to clutter JWT with additional data. About authorization, you can just read the client cookie in the SSR handler and pass it on to the backend in the Authorization header. If needed, a middleware on the server can convert it to a cookie (at the end, it's just another header), so you won't even have to change any backend auth for that.
Another plus of this method is that if you host your backend and frontend together on one machine, NextJS can talk directly to your backend, so fetching the user server-to-server will be even faster than making this request from the frontend.
Finally you if you use OpenApiGenerator, you can modify the client in such a way that it automatically chooses the right address (https://api.yourAwesomeProject.com or http://api_container_name:5000/) for the server based on the presence of a window object and accepts an optional argument for client cookies to forward when needed.
Notes:
window is undefined to distinguish between scenarios