npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@immersa/auth0-jwt-validator

v1.0.2

Published

Utils and tools to validate auth tokens, scopes and permissions using auth0 and nodejs

Downloads

622

Readme

Auth0 JWT Validator

Authentication tools for Node.js that validates JWT Bearer Access Tokens, scopes and permissions using auth0.

Docs Tests License npm codecov

Install

This package supports Node >= 12

npm install @immersa/auth0-jwt-validator

Getting started

The library is agnostic to any NodeJs framework, so we need to use it within custom middlewares since every framework handles the request, response and next in different ways.

With this basic configuration, your api will require a valid Access Token JWT bearer token for all routes.

API Documentation

Complete documentation can be found here.

  • getToken - Validate and get the token from the header request and will return a 401 if a valid JWT bearer token in the request is not provided or has an invalid format.
  • JwtVerifier - Class that verifies the token and will return a 401 if a valid JWT bearer token is not provided. Internally will use the jwksUri to get the public keys form Auth Server Metadata for the verification.
  • requiredPermissions - Check a token's permissions claim to include 1 or more permissions, raises a 403 insufficient_permission error if the value of the scope claim does not include all the given permissions.
  • requiredScopes - Check a token's scope claim to include a number of given scopes, raises a 403 insufficient_scope error if the value of the scope claim does not include all the given scopes.
  • claimEquals - Check a token's claim to be equal a given JSONPrimitive (string, number, boolean or null) raises a 401 invalid_token error if the value of the claim does not match.
  • claimIncludes - Check a token's claim to include a number of given JSONPrimitives (string, number, boolean or null) raises a 401 invalid_token error if the value of the claim does not include all the given values.
  • claimCheck - Check the token's claims using a custom method(predicate) that receives the JWT Payload and should return true if the token is valid. Raises a 401 invalid_token error if the function returns false.

Examples

ExpressJs

auth-middleware.ts

const { jwtVerifier, getToken } = require('auth0-jwt-validator')

export const auth = (opts: JwtVerifierOptions = {}): Handler => {
  const verifier = new jwtVerifier(opts)

  return async (req: Request, res: Response, next: NextFunction) => {
    try {
      const jwt = getToken(req.headers)
      req.auth = await verifier.verify(jwt)
      next()
    } catch (e) {
      next(e)
    }
  }
}

route config

// Config app to use the AuthMIddleware for all the requests
{
  const {auth} = require('my-middleware-folder/auth-middleware')
  ...
  app.use(
    auth({
      issuer: 'https://YOUR_ISSUER_DOMAIN',
      audience: 'https://my-api.com',
      jwksUri: 'https://issuer.example.com/.well-known/jwks.json',
    })
  )
}

permissions-middleware.ts

const { requiredPermissions as _requiredScopes, JWTPayload, RequiredScopes, Permission } = require('auth0-jwt-validator')

// Create a handler as a High order function to be able to use it as a middleware directly in any route
const toHandler =
  (fn: (payload?: JWTPayload) => void): Handler =>
  (req, res, next) => {
    try {
      fn(req.auth?.payload);
      next();
    } catch (e) {
      next(e);
    }
  };

export const requiredPermissions: RequiredScopes<Handler> = (...args) =>
  toHandler(_requiredScopes(...args));

Handler workaround works for the rest of functions: claimIncludes, claimCheck, claimEquals and requiredScopes

Route config

const {requiredPermissions, Permission} = require('my-middleware-folder/permissions-middleware')
// Use enum for known permissions
{
  app.get('/admin/edit', requiredPermissions(Permission.Enhanced),
     (req, res) => { ... });
}

custom-validation-middleware.ts

const { claimCheck as _claimCheck } = require('auth0-jwt-validator')

// Use the previous Handler function

export const claimCheck: RequiredScopes<Handler> = (...args) =>
  toHandler(_claimCheck(...args));

Route config

const {claimCheck} = require('my-middleware-folder/custom-validation-middleware')
...
app.get(
  '/api/admin/edit',
  claimCheck(({ isAdmin, roles }) => isAdmin && roles.includes('editor')),
  (req, res, next) => {
    // ...
  }
)

AdonisJs

Middleware/AuthRequest.ts

import { getToken, JwtVerifier } from 'auth0-jwt-validator'

export default class AuthRequest {
  public async handle(ctx: HttpContextContract, next: () => Promise<void>) {
    const token = getToken(ctx.request.headers())
    const verifier = new JwtVerifier({
      issuer: 'https://YOUR_ISSUER_DOMAIN',
      audience: 'https://my-api.com',
      jwksUri: 'https://issuer.example.com/.well-known/jwks.json',
    })

    const payload = await verifier.verify(token)
    ctx.auth = { token, payload }

    await next()
  }
}

Don't forget to inform Typescript about the new props in context. Check how to do it here

kernel.ts

Server.middleware.register([() => import('App/Middleware/AuthRequest')])

Middleware/PermissionsRequest.ts

import { requiredPermissions } from 'auth0-jwt-validator'

export default class PermissionsRequest {
  public async handle(
    ctx: HttpContextContract,
    next: () => Promise<void>,
    permissions: string[] | string
  ) {
    const { payload } = ctx.auth || {}
    requiredPermissions(permissions)(payload)

    await next()
  }
}

kernel.ts

Server.middleware.registerNamed({
  permissions: () => import('App/Middleware/PermissionsRequest'),
})

Route

import { Permission } from 'auth0-jwt-validator'
Route.get('dashboard', 'UserController.dashboard').middleware(
  `permissions:${Permission.Enhanced}`
)

Error Handling

This SDK raises errors with err.status and err.headers according to rfc6750. So for error handling consider the following premises:

  • res.statusCode set from err.status
  • res.statusMessage set according to the status code.
  • The body will be the HTML of the status code message when in production environment, otherwise will be err.stack.
  • Any headers specified in an err.headers object.

The error_description in the WWW-Authenticate header will contain useful information about the error, which you may not want to disclose in Production.

What is Auth0?

Auth0 helps you to easily:

  • Implement authentication with multiple identity providers, including social (e.g., Google, Facebook, Microsoft, LinkedIn, GitHub, Twitter, etc), or enterprise (e.g., Windows Azure AD, Google Apps, Active Directory, ADFS, SAML, etc.)
  • Log in users with username/password databases, passwordless, or multi-factor authentication
  • Link multiple user accounts together
  • Generate signed JSON Web Tokens to authorize your API calls and flow the user identity securely
  • Access demographics and analytics detailing how, when, and where users are logging in
  • Enrich user profiles from other data sources using customizable JavaScript rules

Why Auth0?

License

This project is licensed under the MIT license. See the LICENSE file for more info.

Contributing

Commits should follow the next format:

type(scope): message

Example:

test(k2-1234): Add pending tests

Type

Must be one of the following:

build: Changes that affect the build system or external dependencies (example scopes: npm)

ci: Changes to our CI configuration files and scripts (examples: GitHub Actions, Hooks)

docs: Documentation only changes

feat: A new feature

fix: A bug fix

perf: A code change that improves performance

refactor: A code change that neither fixes a bug nor adds a feature

test: Adding missing tests or correcting existing tests

IMPORTANT: feat, fix and perf are types that always trigger a new release.

Scope

Must be the ticket/task Id

Copyright

This package is a custom implementation of:

express-oauth2-jwt-bearer