Trouble testing out role based redirects with external JWT provider

Hi,

We’re looking into using role based redirects with an external JWT provider for a project - Role-based access control with JWT | Netlify Docs. The docs are a bit short so to fully understand how it works we wanted to set up a quick test. I’ve created a test site and added some redirect rules so access to one page requires a role. I’ve added a JWT secret in Netlify. From what I’ve read, it seems like the value of the JWT ultimately is saved in a cookie called nf_jwt - so as a quick test I created a JWT with the required role and detail and saved it to a cookie with this name and navigated to the gated page - but I’m not allowed in. Instead it hits the lower redirect rule to take me to the homepage.
Do you have any further information on this. The docs do not talk about needing to write code to set a cookie called nf_jwt - so is this something that would be taken care of by Netlify. In my mind I thought it would work by setting up a redirect to my app (this is separate to this static site) if you go to a protected page and have no role. From there you would get the JWT and be redirected to the site and would then get in. But I feel like I’m missing something?

Thanks,

Katrina

I was looking at this example as well - https://jwt-auth-test.netlify.app/ - which seems to redirect you if you don’t have the role and that comes back with a set-cookie nf_jwt value in the response - but this doesn’t seem to ultimately be working as I click login and nothing happens.

Hi. Further to ^ I’ve followed roughly this blog - Restrict access to your sites with role based redirects

When I hit the homepage of my site I just fire off to a Netlify function for now which sets an http-only secure cookie called jwt and the value is the jwt I create in this way:

const createJWT = () =>
jwt.sign(
{
exp: getExpiry(),
app_metadata: {
authorization: {
roles: [“editor”, “admin”]
}
},
user_metadata: {
name: “Jane Doe”,
email: “doe@adear.com”,
},
user_id: uuidv4()
},
“mysecret”
);

I then have a netlify.toml file with a couple of redirects:

[[redirects]]
from = “/news/"
to = "/news/

status = 200
conditions = {Role = [“admin”]}
force = true

[[redirects]]
from = “/news/*”
to = “/”
status = 302
force = true

I would expect with ^ that if I go to the homepage, see that the cookie is set, then try to go to news I will get in. But regardless of whether the cookie is set or not I get redirected back to the homepage. I have set the JWT token in the Netlify UI. Any ideas why this wouldn’t work as expected would be gratefully received.

Thanks,

Katrina

Hey @katcoutts! :wave:t2:

For starters, yes, the docs on Netlify Identity + External JWT Providers are sparse and generally require some digging of our own. Kudos on what you’ve found! :grin:

To the point of cookies, yes I believe that the _redirects engine itself is exclusively wired to check for, and use a signed JWT in a cookie labeled nf_jwt, so you should be correct there. As long as the embedded JWT is signed with the same value you put in the ‘secret’ field for the external provider in the Netlify UI, that should work.

For reference, here’s the shape of a JWT issued by Netlify’s own provider service, GoTrue

{
  "exp": 1605893544,
  "sub": "e6abc00c-b1ae-4a6f-8aac-8aeabcd89614",
  "email": "test@jon.fm",
  "app_metadata": {
    "provider": "email",
    "roles": [
      "member",
      "admin",
    ]
  },
  "user_metadata": {
    "full_name": "Test Jon"
  }
}

So I think your issue may just be in the app_metadata object. It looks like you’re doing:

app_metadata: {
  authorization: {
    roles: [
      “editor”,
      “admin”
    ]
  }
}

and I think you’d just want:

app_metadata: {
  roles: [
    “editor”,
    “admin”
  ]
}

e.g. de-nesting and removing the Authorization object. I haven’t personally executed an Identity site with an external provider before, but I don’t think the "provider": "email" bit should be necessary for you. I don’t think the _redirections engine should care about that field.

The other gotcha to watch out for is the exp field within the JWT. The _redirects engine adheres to the expiration date so if you submit a cookie with a JWT whose exp has passed, you will not be granted access.

I hope that helps for a first pass!


Jon

Oh thank you. I’ll try that. I just copied the shape of it from a blog.

Unfortunately not fixing it.

Are you able to share the URL of the site you’re working with? I’d be happy to poke around on it to see what I can find if you’d like :slight_smile:

Hi,
So as this is just a proof of concept to understand how the JWT works, it’s just a netlify template site. I have the JWT stuff in a branch which is available to see here - https://deploy-preview-1--unruffled-volhard-fd8e94.netlify.app/.
So if you land on the homepage you should see that you get a nf_jwt cookie set and that should allow you to go to the news page. But instead of getting into the homepage it’s redirecting to homepage.

I was taking inspiration from this blog. However, when I access the github repo connected to this example site there’s quite a lot more code in there and the redirect file isn’t actually specifying anything about roles. It appears that’s all being looked and and dealt with in JS. My understanding was for this to work, you just need to ensure you get that cookie set, use the secret that Netlify has in the UI and then set up the redirects. It’s a bit confusing.

Hi Kat,

It appears to me that you have not activated our identity feature, which I believe is required to make JWT’s work. You can turn it on here, and I think that things may work better for you:

D’oh! That’d do it! Thanks for following up @fool :raised_hands:t2:

@katcoutts apologies for the delay but happy to continue hashing this out if that doesn’t work! I have a sweet spot for Identity :slight_smile:


Jon

Hi. Turns out I was stupid. I hadn’t manually enabled Netlify Identity, but I think because I created a template site it was enabled. You can’t have that enabled and use JWT with an external provider. Disabling Netlify Identity made it work!
Thank you for taking the time to offer some advice.