As part of our filing for Chapter 11 bankruptcy relief, Akamai has acquired select assets from Edgio, including certain customer contracts from our content delivery, applications, and security businesses, but not including Uplynk. We encourage any active Edgio delivery, applications, or security customers that are not already engaged with Akamai to migrate their services, to contact their local Akamai office or support@edg.io as soon as possible to help avoid service interruptions. Service will end on January 15, 2025.


Any Edgio Uplynk customers can reach out to support@uplynk.com for any questions or concerns.

Edgio

JWT Validation

You may only deploy this edge function using CDN-as-Code due to Node.js dependencies. It will not work when deployed through the Edgio Console.
This example uses Edge Functions to validate a JSON Web Token (JWT) sent by a client. Handling this validation at the edge can help to offload the work from the origin server, and offer a more secure and efficient way to verify the token. Additionally, you can extend this edge function to check whether the client is authorized to access a protected resource or to verify the client’s identity.

Router Configuration

In the Edgio router, you can use the edge_function feature to specify the path to the edge function that will handle the JWT validation.
JavaScriptroutes.js
1import {Router, edgioRoutes} from '@edgio/core';
2
3export default new Router().use(edgioRoutes).post('/jwt', {
4 edge_function: './edge-functions/validate.js',
5});

Edge Function

This edge function uses the jsrsasign libary to validate a JWT signed with a HS256, HS384, or HS512 algorithm. It expects to receive a POST request with the following JSON payload:
  • token: Required. This parameter must be set to the JWT that will be validated.
  • pubKey: By default, the JWT will be decoded using a default signing key (i.e., your-256-bit-secret) defined within the JWT_SECRET environment variable. However, you may decode it using a custom signing key by defining a pubKey parameter.
    This example allows you to pass a signing key to make it easier to test JWT validation through this edge function. However, signing keys should be kept secret. For example, a client should not pass a signing key within the request payload.
Upon completion, this edge function will report the result in the response.
Sample curl request:
Bash
1curl -X POST -d '{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"}' https://edgio-community-examples-v7-ef-jwt-validation-live.glb.edgio.link/jwt
Sample response:
{"valid":true,"alg":"HS256","payload":{"sub":"1234567890","name":"John Doe","iat":1516239022}}
Alternatively, you can validate JWTs by submitting the form on the following web page:
https://edgio-community-examples-v7-ef-jwt-validation-live.glb.edgio.link/

Code

This edge function’s code:
JavaScriptedge-functions/validate.js
1import { KJUR, KEYUTIL } from 'jsrsasign'
2import { Buffer } from 'buffer'
3
4// Set up some polyfills to allow this code to run locally and when deployed:
5global.process = global.process || { env: {} }
6const fromBase64 = (str) => Buffer.from(str, 'base64').toString()
7
8export async function handleHttpRequest(request, context) {
9 Object.assign(process.env, context.environmentVars)
10
11 // Extract the token and any other objects from the request.
12 const { token, ...other } = await request.json()
13
14 // Split out the header and payload from the cleartext token and determine the right algorithm to use.
15 const [header, payload] = token.split('.')
16 const { alg } = JSON.parse(fromBase64(header))
17
18 let validationComponent = null
19 let valid = false
20 const resp = { valid }
21
22 try {
23 // For HSxxx algorithms, the validation requires a plaintext secret key.
24 // For RSxxx, ESxxx, and PSxxx algorithms, a public key is required instead.
25 // The public key is expected to be part of the request payload and be named pubKey;
26 // the secret key SHOULD NOT be part of the payload.
27 // Note that for demo purposes (being able to set an arbitrary signing key) this
28 // version of the EF will use the secret from `pubKey` if it exists.
29 if (/^HS/i.test(alg)) {
30 if ('pubKey' in other) {
31 validationComponent = other.pubKey
32 } else {
33 validationComponent = process.env.JWT_SECRET
34 }
35 } else if (/^[REP]S/i.test(alg)) {
36 validationComponent = KEYUTIL.getKey(other.pubKey)
37 } else {
38 return new Response('Invalid JWT alg specified.', { status: 401 })
39 }
40
41 valid = KJUR.jws.JWS.verifyJWT(token, validationComponent, { alg: [alg] })
42 if (valid === true) {
43 // Only parse the payload if the signature is valid.
44 const decodedPayload = JSON.parse(fromBase64(payload))
45 Object.assign(resp, { valid, alg, payload: decodedPayload })
46 }
47 } catch (e) {
48 // Handle exceptions here.
49 }
50
51 return new Response(JSON.stringify(resp), {
52 status: valid ? 200 : 401
53 })
54}