I recently fought with a nasty error regarding Role Based Access Control and discovered what I believe to be a bug (or rather, undocumented requirements). Learned a lot and thought I’d share.
Setup
- I’m using the netlify identity widget.
- My goal is to restrict access to a particular page
/section/gated
. Only users with theRole=plan:pro
should be allowed. All others should be redirected to a custom/401
page with a 401 status code.
My _redirects
file looked like this.
/section/gated /section/gated 200! Role=plan:pro
/section/gated /401 401!
The Problem
I login with a user, Ben1. I know this user has the role plan:pro
because I manually gave it to him in the netlify identity dashboard. However, when I attempt to access /section/gated
I get redirected to the 401 page.
Frustrating
Ideas:
-
Maybe the redirects didn’t get applied properly in the build. But this would be odd because
- the fallback redirect worked
- the build logs showed me that two redirect rules were processed
Perhaps the build mangled the first redirect rule for some reason… I download the built site which you can do with this button, inspect the
_redirects
file and all looks good.
-
Maybe my rule was incorrectly formatted. Or perhaps there’s something funny about the cycle rule, directing from page A to page A (which could create an endless loop). The example in the docs here specifically states
Role-based redirects do not have a “to” property.
But, ntl debug
actually throws an error if you leave out the to property. Furthermore, when I exclude Role=plan:pro
, the redirect works fine as I have it.
- Maybe it’s a cookie issue. I’ve been testing different sites and logging into different accounts. But,
- I’ve been careful to clear my cache and cookies before testing
- When I request the locked page, I monitor the network via Chrome > Developer Tools > Network. The first call I see is a GET request to
/section/gated
which includes a header like with the jwt.
I plug this into the jwt decoder at jwt.io, decode the jwt, and see that it’s got the correct user, correct user id, correct role, and it’s not expired.
Solution
I finally tried changing the role from ‘plan:pro’ to simply ‘pro’ and it worked. If anyone else is struggling with RBAC, make sure you use a “simple” string for the role.