JWKS, RS256 and consuming OIDC tokens using hapiJS

Nikko Ambroselli
2 min readJul 27, 2017

--

When building Nodejs micro-service APIs I like to use hapijs. Scales well, provides enough out of box to be considered a full framework, extends very easily. Plus plenty of modules! But an API cannot be launched without proper security rules built in.

OpenID Connect

Use it. Its secure, supports access scoping, and embedded identities in session. While there are always new specs when it comes to auth, openid connect is adopted enough that it allows flexibility in the future (the new auth standard will be similar to OIDC)

Adding Auth

When adding auth to a web application that is served on a SPA I prefer the implicit grant flow. This is most practical when maintaining multiple application states. It allows multiple clients to connect to the same API. Also enabling secure browser technologies such as localStorage and JWT we can ensure users information will not be comprised under standard conditions.

The basics of implicit grants are:

  • Web SPA authenticates, asks auth server for token
  • Web SPA stores the token and attaches the token to requests to API
  • API needs to validate and consume token
credit: auth0 for wonderful diagrams

JWT (on the API)

As a prerequisite to JWKS we must add JWT support to our API. Use the hapi-auth-jwt2 hapijs module.

const hapiAuthJwt = require('hapi-auth-jwt2');server.register([hapiAuthJwt ...

JWKS

When verifying JWT Bearer tokens I strongly recommend node-jwks-rsa module. It takes care of creating the key for RS256 decryption. It also caches the cert in memory to prevent flooding of requests to auth server.

Don’t forget to set the default auth strategy for your API. More about that can be found on the documentation page. One thing in particular to note is the verify options. If the issuer or audience is not configured properly verification of the token will fail.

Now that the token is decrypted, you have the credentials available in any route (hint: add scope checking in the controller)

handler: function (req, reply) {
// req.auth.credentials contains the user object
}

Any requests that fail will result in a 401 returned from the API.

In this article we cover the API section of the auth flow. Look forward to covering the web site in the near future!

--

--