blitz icon indicating copy to clipboard operation
blitz copied to clipboard

Authenticate page based on user role

Open frankiesardo opened this issue 3 years ago • 7 comments

What do you want and why?

Blitz offers a way to secure frontend pages out of the box with

Page.authenticate = true

Which is very convenient when you want to ensure the user is logged in.

Another common use case is to secure certain pages for admin use only, but that currently is not supported and must be done manually via useSession.

It would be great to have a shorthand way to specify which pages are accessible to which user roles.

Possible implementation(s)

Page.authenticate already takes two forms: true and { redirectTo: "/login" }

I suggest the map form could take another parameter called { role: "ADMIN"} the same way resolved.authorize() works (single argument or a list of roles)

That way all these combinations are valid:

Page.authenticate = true // user must be logged in
Page.authenticate = { redirectTo: "/login" } // user must be logged in and redirects otherwise
Page.authenticate = { role: ["ADMIN", "USER"] } // user must be logged in and with role "ADMIN" or "USER"
Page.authenticate = { role: "ADMIN", redirectTo: "/login" } // user must be logged in with role "ADMIN" and redirects otherwise

One objection to this implementation might be that somebody wants to have a custom redirect logic based on the failure e.g. redirect to /login if unauthenticated and redirect to /home if unauthorized. I'm not sure if that is a common enough use case, but if that's the case then maybe redirectTo can be a function that takes the current user and returns a path.

frankiesardo avatar May 27 '21 07:05 frankiesardo

Great suggestion!

MrLeebo avatar May 29 '21 04:05 MrLeebo

This looks super nice, would like to know how hard would be this

andresgutgon avatar Aug 01 '21 12:08 andresgutgon

@andresgutgon shouldn't be too hard. Requires changing this line: https://github.com/blitz-js/blitz/blob/canary/packages/core/src/blitz-app-root.tsx#L51 and also the source of useAuthorizeIf to support roles.

flybayer avatar Aug 04 '21 19:08 flybayer

Just to confirm. This authentication/authorisation on the Page works at client site right? I mean. This is not run in the server. So we get the roles with useSession?

The magic is that with Babel you add a HOC on nextjs pages that understand this Page.authenticate?

andresgutgon avatar Aug 05 '21 07:08 andresgutgon

@andresgutgon that's correct, except that inside useAuthorize we don't use the publicData store directly instead of through useSession.

flybayer avatar Aug 05 '21 14:08 flybayer

any updates on this @flybayer ?

samrxth avatar Mar 14 '22 10:03 samrxth

any updates on this @flybayer ?

I also wonder that, this looks pretty cool

ragokan avatar Apr 14 '22 13:04 ragokan