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

ez-jwt

v1.1.2

Published

JSON Web Token (JWT) and JSON Web Signature (JWS) validation using WEB Cryptography API

Downloads

7

Readme

ez-jwt

JSON Web Token (JWT) and JSON Web Signature (JWS) validation using WEB Cryptography API.

npm npm bundle size Top Language MIT License

Features

  • Validates JWT/JWS signature, returns JWT claims
    • jwtValidate(jwt) returns JWT claims
    • jwsValidate(jws) returns JWS (JOSE) header and JWS payload
  • Accepts JWS Compact Serialization format for JWT/JWS
  • Uses Web Cryptography API to
    • import keys encoded in the JSON key format (JWK)
    • validate messages using digital signatures or MACs (JWS)
  • Understands all standard algorithms for digital signatures and MACs (according to RFC 7518). Particular algorithm support depends on a browser.
  • Сompliant with Javascript Object Signing and Encryption (JOSE) RFCs
  • Tiny package
  • ES6 module, typings available

Install

npm i ez-jwt

Usage

The main function to validate a JWT and obtain the JWT claims is jwtValidate(). Let's use RFC 7515 example JWT.

// JWS header is { typ: 'JWT', alg: 'HS256' }
// JWT claims is { iss: 'joe', exp: 1300819380, 'http://example.com/is_root': true }
const token =
  'eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJle' +
  'HAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnV' +
  'lfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk';

This token has no information about the key to validate it, so we need to provide the key explicitly. The public key to validate the token is present in the same example.

const jwk = {
  kty: 'oct',
  k: 'AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow'
};

Use jwtValidate() and provide the key to validate the token, get JWT claims.

import { jwtValidate } from 'ez-jwt';

jwtValidate(token, {keys: jwk})
  .then((claims) => {
    // JWT is valid
    // claims value is { iss: 'joe', exp: 1300819380, 'http://example.com/is_root': true }
  });

We don't need to provide any keys if a token JWS header has information about the key to validate it. See Key providers.

JWT/JWS validation

Input JWT/JWS should be in JWS Compact Serialization format: a string of three BASE64URL-encoded parts (header, payload, and signature), separated by . symbols.

Any digitally signed JWT is a JWS with a well-defined payload, which is JWT Claims.

| Compact Serialization Format | BASE64URL(JSON( x )) | . | BASE64URL( x ) | . | BASE64URL( x ) | |:---|:---:|:---:|:---:|:---:|:---:| | JWS | JWS Header | | ArrayBuffer | | JWS Signature | | JWT | JWS Header | | JSON(JWT Claims) | | JWS Signature |

JWT validation process performed by jwtValidate():

  • Validate JWT as JWS using jwsValidate().
    • Split the input JWS into three parts: header, payload, signature.
    • BASE64URL_DECODE() all the parts.
    • UTF-8 decode and JSON parse the header, get JWS header.
    • Check JWS header parameter crit (should be undefined).
    • Check JWS header parameter alg (should be one of the standard algorithms).
    • Apply the key provider function to the header and get an array of keys.
    • Filter key array by key ID, algorithm, usage, and operations.
    • Use the remaining key(s) to verify JWS signature.
    • Return JWS header and payload.
  • Check JWS header parameters typ (should be undefined or equals 'JWT') and cty (should be undefined).
  • UTF-8 decode and JSON parse JWS payload, get JWT claims object.
  • Validate JWT claims exp and nbf (if present).
  • Return JWT claims.

Keys providers

To validate a JWS Signature the correct public key is required. The key should be provided to jwsValidate() function. A token issuer can provide the public key to validate the token in several ways and different formats.

JWK/JWKS public key

This is the main format of key data supported by the package.

  • A JWK is provided in JWS header (parameter jwk).
  • One or more JWK is known to the application.
  • URI of JWKS endpoint is provided in JWS header (parameter jku).
  • URI of JWKS endpoint is known to the application (for example .well-known/jwks.json for OAuth2 applications).

The default key provider jwsHeaderKeysProvider() gets jwk parameter key and adds all the keys from JWKS endpoint defined by jku parameter. One can add some more application keys by passing them as an argument for jwsHeaderKeysProvider(appKeys). appKeys value can be JWK, JWK[], or JWKS object.

Two application keys providers jwkAppKeysProvider() and jwkAppUriProvider() ignore JWS header parameters and provide application keys only.

One can design a custom key provider function and pass it to jwsValidate(). Key provider is a function that takes JWS header and returns keys to validate the JWS.

type JwsKeyProvider = (h: JWSHeader) => Promise<JWK[]>;

Key provider functions summary: | Key provider | JWS header jkw | JWS header jku | Application JWK/JWK[]/JWKS | Application JWKS endpoint | |---|:---:|:---:|:---:|:---:| |jwsHeaderKeysProvider()| + | + | | | |jwsHeaderKeysProvider(appKeys)| + | + | appKeys | | |jwkAppKeysProvider(appKeys)| | | appKeys | | |jwkAppUriProvider(jwks_uri)| | | | jwks_uri |

Note: one can download all the keys from JWKS endpoint to appKeys variable in advance and use jwkAppKeysProvider(appKeys) (or jwsHeaderKeysProvider(appKeys)) provider instead of jwkAppUriProvider().

JWKS endpoint

A token issuer JWKS endpoint returns all the public keys the issuer uses to sign tokens. One can filter the keys by kid or try to use all the keys. For example, Google's OpenID Connect services JWKS endpoint returns the following two keys:

{
  "keys": [
    {
      "kid": "0a7dc12664590c957ffaebf7b6718297b864ba91",
      "use": "sig",
      "kty": "RSA",
      "alg": "RS256",
      "e": "AQAB",
      "n": "7NfiTQcshWgrEdKbHC2e..............eNVz39274ippJSQ"
    },
    {
      "kid": "bc49530e1ff9083dd5eeaa06be2ce437f49c905e",
      "use": "sig",
      "kty": "RSA",
      "alg": "RS256",
      "e": "AQAB",
      "n": "xPXUFDnAQQ5daLQTcQsV..............Na3BbnAhj7miR0w"
    }
  ]
}

X.509 certificate public key

Public key data can be provided X.509 certificate as a SubjectPublicKeyInfo object. JWS header parameters x5u, x5c, x5t, x5t#S256 provide key data in form of an X.509 certificate.

Web Cryptography API doesn't support X.509 certificate processing so the package doesn't support those keys data. One can create a custom key provider function and use a third-party library to parse X.509 cert and convert key data to JWK format.