fastify-jwt-jwks
Version:
JWT JWKS verification plugin for Fastify
127 lines (92 loc) • 4.99 kB
Markdown
# fastify-jwt-jwks
[](https://npm.im/fastify-jwt-jwks)
[](https://github.com/nearform/fastify-jwt-jwks/actions/workflows/ci.yml)
JSON Web Key Set (JWKS) verification plugin for Fastify, internally uses [@fastify/jwt](https://www.npmjs.com/package/@fastify/jwt).
#### Note
JSON Web Key Sets (JWKS) are used to verify that a signed JWT originated from a particular authorization server, and that the token hasn't been tampered with. If you are looking to implement JWT authentication in your Fastify application you may be looking for [@fastify/jwt](https://www.npmjs.com/package/@fastify/jwt).
## Installation
Just run:
```bash
npm install fastify-jwt-jwks --save
```
## Usage
Register as a plugin, providing one or more of the following options:
- `jwksUrl`: JSON Web Key Set url (JWKS). The public endpoint returning the set of keys that contain amongst other things the keys needed to verify JSON Web Tokens (JWT). Eg. https://domain.com/.well-known/jwks.json
- `audience`: The intended consumer of the token. This is typically a set of endpoints at which the token can be used. If you provide the value `true`, the domain will be also used as audience. Accepts a string value, or an array of strings for multiple audiences.
- `issuer`: The domain of the system which is issuing OAuth access tokens. By default the domain will be also used as audience. Accepts a string value, or an array of strings for multiple issuers.
- `secret`: The OAuth client secret. It enables verification of HS256 encoded JWT tokens.
- `complete`: If to return also the header and signature of the verified token.
- `secretsTtl`: How long (in milliseconds) to cache RS256 secrets before getting them again using well known JWKS URLS. Setting to 0 or less disables the cache. Defaults to 1 week.
- `cookie`: Used to indicate that the token can be passed using cookie, instead of the Authorization header.
- `cookieName`: The name of the cookie.
- `signed`: Indicates whether the cookie is signed or not. If set to `true`, the JWT will be verified using the unsigned value.
- `namespace`: A string used to namespace the decorators of this plugin. This is to allow this plugin to be applied multiple times to a single Fastify instance. See the description of the [namespace parameter](https://github.com/fastify/fastify-jwt?tab=readme-ov-file#namespace) in @fastify/jwt.
Since this plugin is based on the [@fastify/jwt](https://www.npmjs.com/package/@fastify/jwt) `verify`, it is also possibile to pass the options documented [here](https://github.com/fastify/fastify-jwt#verify), see the example below.
Once registered, your fastify instance and request will be decorated as describe by `@fastify/jwt`.
In addition, the request will also get the `authenticate` decorator.
This decorator can be used as `preValidation` hook to add authenticate to your routes. The token information will be available in `request.user`.
Example:
```js
const fastify = require('fastify')
const server = fastify()
await server.register(require('fastify-jwt-jwks'), {
jwksUrl: '<JWKS url>',
audience: '<app audience>'
})
server.get('/verify', { preValidation: server.authenticate }, (request, reply) => {
reply.send(request.user)
})
server.listen(0, err => {
if (err) {
throw err
}
})
```
You can configure there to be more than one JWT API audience:
```js
await server.register(require('fastify-jwt-jwks'), {
jwksUrl: '<JWKS url>',
audience: ['<app audience>', '<admin audience>']
})
```
You can include [@fastify/jwt verify](https://github.com/fastify/fastify-jwt#verify) options:
```js
await server.register(require('fastify-jwt-jwks'), {
jwksUrl: '<JWKS url>',
audience: ['<app audience>', '<admin audience>'],
cache: true, // @fastify/jwt cache
cacheTTL: 100, // @fastify/jwt cache ttl
errorCacheTTL: -1 // @fastify/jwt error cache ttl
})
```
You can also use the `namespace` option to apply this plugin multiple times to the same Fastify instance, in order to perform JWT verification with different JWKs URLs:
```js
await server.register(require('fastify-jwt-jwks'), {
jwksUrl: '<JWKS url>',
audience: '<app audience>'
})
await server.register(require('fastify-jwt-jwks'), {
jwksUrl: '<JWKS url 2>',
audience: '<app audience 2>',
namespace: 'newToken'
})
server.get('/verify',
{
preValidation: async function (request, reply) {
try {
await server.authenticate()
} catch (err) {
await server.newTokenAuthenticate()
}
}
},
(request, reply) => { reply.send(request.user) }
)
```
## Contributing
See [CONTRIBUTING.md](./CONTRIBUTING.md)
## Developer notes
### Tests
Tests are currently split into **unit** and **integration** tests.
## License
Copyright NearForm Ltd. Licensed under the [Apache-2.0 license](http://www.apache.org/licenses/LICENSE-2.0).