Git Product home page Git Product logo

fastify-jwt-jwks's Introduction

fastify-jwt-jwks

Package Version ci

JSON Web Key Set (JWKS) verification plugin for Fastify, internally uses @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.

Installation

Just run:

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.
  • 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 in @fastify/jwt.

Since this plugin is based on the @fastify/jwt verify, it is also possibile to pass the options documented here, 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:

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:

await server.register(require('fastify-jwt-jwks'), {
  jwksUrl: '<JWKS url>',
  audience: ['<app audience>', '<admin audience>']
})

You can include @fastify/jwt verify options:

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:

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

Developer notes

Tests

Tests are currently split into unit and integration tests.

License

Copyright NearForm Ltd. Licensed under the Apache-2.0 license.

fastify-jwt-jwks's People

Contributors

admataz avatar brainrepo avatar bredikhin avatar dependabot[bot] avatar ergusto avatar gilach avatar github-actions[bot] avatar guilhermelimak avatar ilteoood avatar marco-ippolito avatar mattmazzola avatar mcollina avatar melkornemesis avatar nlindley avatar notwoods avatar optic-release-automation[bot] avatar radomird avatar ramonmulia avatar ruanmartinelli avatar salmanm avatar sameer-coder avatar shogunpanda avatar simoneb avatar sundeqvist avatar taylorjames avatar toomuchdesign avatar uzlopak avatar wilkmaia avatar williamlines avatar zenpaul avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

markrzen zenpaul

fastify-jwt-jwks's Issues

Cannot get to work with Microsoft Entra

The keys array returned from Microsoft Entra do not include an "alg" attribute, thus causing the following line of code to fail to retrieve the key, despite there being a matching "kid", there is no "alg"

const key = body.keys.find(k => k.alg === alg && k.kid === kid)

Microsoft Entra keys retrieved from here: https://login.microsoftonline.com/common/discovery/v2.0/keys

Microsoft Documentation here: https://learn.microsoft.com/en-us/entra/identity-platform/access-tokens#validate-the-signature

Note, that the use of "alg" is optional, per the spec: https://datatracker.ietf.org/doc/html/rfc7517#section-4.4

Feature request: support namespacing of decorator functions

I would like to be able to apply this plugin to the same Fastify instance more than once, providing different JWK URLs, so that I can have a single Fastify server verify JWTs from more than one source. Currently, there is no way to do so without encountering decorator name collisions. @fastify/jwt provides a namespace option to address this problem. I propose implementing the same feature in this plugin.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.