Validate the signature of a crypto key in Cloudflare Pages Functions

Validate the signature of a crypto key in Cloudflare Pages Functions

In this Article

Overview

Cloudflare Workers don’t run on node.js they don’t run on browser javascript either. The Workers runtime uses the V8 engine and implements many of the Browser Apis standards. If you want to know more about the Worker runtime have a peek here.

Pages functions run on the same workers environment. Chances are at some stage you might be writing an authentication middleware to check the signature validity of a json web token using a json web key. Here is how to do that.

Validating the signature

We mentioned in the previous paragraph how the runtime environment is not node.js so we can’t rely on some of the packages that are out there. However Cloudflare supports WebCrypto. Best for you to have a look here for the updated list of supported algorithms.

Now here is the pill of code:

import { base64url } from 'rfc4648'

/**
 * Validate the token signature using a json web key.
 * @param jwk - the jwk (usually fetched from well-known)
 * @param token - the jwt to verify the signature for
 */
export const isValid = async (jwk: JsonWebKey, token: string): Promise<boolean> => {
  // first import the key
  const key: CryptoKey = await crypto.subtle.importKey(
    'jwk',
    jwk,
    // this algo is supported for verify in the worker runtime
    { name: 'RSASSA-PKCS1-v1_5', hash: { name: 'SHA-256' } },
    false,
    ['verify'],
  )
  // then decode the token
  const [header, payload, signature] = token.split('.')
  const decoder = new TextDecoder()
  // using the rfc4648 library 
  const decodedToken = {
    header: JSON.parse(decoder.decode(base64url.parse(header, { loose: true }))),
    payload: JSON.parse(decoder.decode(base64url.parse(payload, { loose: true }))),
    signature: base64url.parse(signature, { loose: true }),
    raw: { header, payload, signature },
  }
  // encode the raw header and payload
  const data = new TextEncoder().encode(`${decodedToken.raw.header}.${decodedToken.raw.payload}`)
  // check that the signature is valid
  return await crypto.subtle.verify(
    { name: 'RSASSA-PKCS1-v1_5', hash: { name: 'SHA-256' } },
    key,
    decodedToken.signature,
    data,
  )
}

That’s how to verify the signature for a json web token using a json wen key in Cloudflare Workers and Pages Functions.