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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@instructure/inst-node-jwt

v5.6.0

Published

express JWT middleware

Readme

Inst-node-JWT

A decently opinionated Expressjs middleware for verifying JWTs (JSON Web Tokens).

Lets you authenticate HTTP requests using JWT tokens. Both signs and verifies JWTs. Handles multiple secrets and key rotation. Built on jsonwebtoken

Install

npm install inst-node-jwt

inst-node-jwt is configured using environment variables:

  • AUTH_SECRET - The secret(s) used for verifying JWTs. Secrets are :-separated key-value pairs. Multiple secrets are space-separated. See Keystore for more details.
  • MAX_JWT_AGE - if a JWT is not given an exp claim (expiration date), then the JWT will be rejected if the claim's iat (signed-at date) is more than MAX_JWT_AGE in the past. Uses zeit/ms format. If not set, JWTs without an exp claim will never expire.
  • REQUIRE_AUTH - used for development.
    • When set to 'false' (case-insensitive) or '0', JWTs will not be required by this library's middleware
    • When set to anything else (e.g. 'true'), JWTs are required with every request
    • When not set, auth.required() returns true iff NODE_ENV === 'production'

Usage

Set the AUTH_SECRET environment variable; e.g. with AUTH_SECRET="kid:secret" node myfancyapp.js.

var auth = require('inst-node-jwt')

if (auth.required()) {
  app.use([auth.middleware, auth.errorHandler])
}

The middleware will verify JWTs that are included in the request's query string as token:

example.com/route?token=<jwt-here>

or as an authorization header:

Authorization: Bearer <jwt-here>

It prefers the query string over the header.

If the token is valid, res.locals.JWTPayload will be set with the token's payload.


About

inst-node-jwt fills a need for a simple JWT middleware that can handle key rotation.

required(): defaults to the boolean value of NODE_ENV === 'production' but can be overridden to return something else by setting REQUIRE_AUTH. (see description of REQUIRE_AUTH below) Use this function to determine whether or not to use this library's middleware in your Expressjs middleware stack

middleware() / errorHandler(): two Expressjs middlewares that should be called early in your middleware pipeline. If middleware() is unable to verify a JWT, it will abort the request and send an error to the errorHandler() middleware, which will return a 401 error with a JSON description of the error.

Keystore

The keystore is initialized with values from the AUTH_SECRET environment variable. It can contain as many secrets as needed (within the max length of an environment variable). Each secret consists of a kid and a key value, separated by a :.

const auth = require('inst-node-jwt')

(async () => {
  // DO NOT SET YOUR SECRETS INLINE LIKE THIS IN A PRODUCTION APP
  //   see https://12factor.net/config
  const s1 = Buffer.from("secret1").toString("base64")
  const s2 = Buffer.from("secret2").toString("base64")
  process.env.AUTH_SECRET = `secret1:${s1} secret2:${s2}`

  const keystore = await auth.keystoreBuilders.fromEnv()

  console.log(keystore.secret1.toString()) // secret1
  console.log(keystore.secret2.toString()) // secret2
})()

The kid, or key id, is included in the header section of a JWT is an easy way of identifying which secret was used to sign that JWT.

The key value is the base64-encoded secret. Note that inst-node-jwt will sign and verify JWTs by decoded that secret using base64 and use the original random bytes. This is based on jsonwebtoken's behavior, outlined [here] (https://github.com/auth0/node-jsonwebtoken/issues/208#issuecomment-231861138)

A secret that has no kid: is known as the default key. There can only be one default key; all other keys without kids will be ignored.

const auth = require('inst-node-jwt')

(async () => {
  // DO NOT SET YOUR SECRETS INLINE LIKE THIS IN A PRODUCTION APP
  //   see https://12factor.net/config
  const s1 = Buffer.from("secret1").toString("base64")
  const s2 = Buffer.from("secret2").toString("base64")
  const s3 = Buffer.from("secret3").toString("base64")
  process.env.AUTH_SECRET = `secret1:${s1} ${s2} ${s3}`

  const keystore = await auth.keystoreBuilders.fromEnv()

  console.log(keystore.secret1.toString()) // secret1
  // Notice that secret2 has been overridden
  console.log(keystore.default.toString()) // secret3
})()

Verification

inst-node-jwt is capable of verifying JWTs using different methods. If a kid is included in the JWT header, inst-node-jwt will attempt to verify using the key that matchs the kid, if there is one. If that fails, it will verify using the default key. Otherwise, it will try using every key in the keystore to verify.

NOTE: the HS256 algorithm is disallowed for security purposes. A JWT that was signed using HS256 will be rejected by the verification process. To check if a JWT was signed with HS256, base64-decode the JWT (e.g. at https://jwt.io/) and make sure the "alg" key in the header doesn't equal "HS256"

Signing

inst-node-jwt can also sign tokens, e.g. for testing purposes.

const auth = require('inst-node-jwt')

(async () => {
  // DO NOT SET YOUR SECRETS INLINE LIKE THIS IN A PRODUCTION APP
  //   see https://12factor.net/config
  const s1 = Buffer.from("secret1").toString("base64")
  const s2 = Buffer.from("secret2").toString("base64")
  process.env.AUTH_SECRET = `${s1} secret2:${s2}`

  const token1 = await auth.createToken({foo: "bar"})
  const payload1 = await auth.verifyToken(token1)
  console.log(payload1) // { "foo": "bar" }

  const token2 = await auth.createToken({bar: "baz"}, "secret2")
  const payload2 = await auth.verifyToken(token2)
  console.log(payload2) // { "bar": "baz" }
})()

Development

Linter

We use eslint and prettier to check code correctness and impose style, respectively. These tools have been set up to stay out of your way while keeping style consistent, as well as occasionally pointing out possible errors.

Every commit needs to be linted before pushing: docker-compose run --rm app yarn run lint:fix.

We recommend using editor integrations or adding a pre-push git hook to take care of this automatically. You can do this by running this command once from the root of the node-jwt directory: ln -s ../../pre-push.sh .git/hooks/pre-push