Next.js Discord

Discord Forum

Middleware JWT token verifiction using Jose

Unanswered
Olive Warbler posted this in #help-forum
Open in Discord
Olive WarblerOP
I'm trying to use Jose to verify a JWT token. It uses RS256 and I have a static public key which I import with jose.importSPKI. The issue is that this function uses node:crypto, which is not supported in edge functions. Has anybody faced this issue?

11 Replies

Olive WarblerOP
I'm already using Jose, but the inbuild function (importSPKI()) uses node:crypto
Olive WarblerOP
It also uses the node:crypto package under the hood
Olive WarblerOP
I'm really losing my mind over this, since JWT verification in a middleware seems like a standard feature to me. Am I overlooking something obvious?
American Crow
Don't know what you are doing in the middleware but jose can run on edge:
https://github.com/panva/jose/issues/301
Olive WarblerOP
This is what I'm doing:

const publicKey = await jose.importSPKI(process.env.PUBLIC_KEY!, "RS256");
const { payload, protectedHeader } = await jose.jwtVerify(authToken, publicKey);
The problem is that importSPKI relies on node:crypto, which cannot run in edge functions.
The error when trying to do this is:
Error: atob() called with invalid base64-encoded data. (Only whitespace, '+', '/', alphanumeric ASCII, and up to two terminal '=' signs when the input data length is divisible by 4 are allowed.)
    at (node_modules/jose/dist/browser/runtime/asn1.js:62:35)
    at (node_modules/jose/dist/browser/runtime/asn1.js:123:11)
    at (node_modules/jose/dist/browser/key/import.js:10:11)
    at (app/lib/auth.ts:49:28)
    at (middleware.ts:20:26)
    at (middleware.ts:10:26)
    at (node_modules/next/dist/esm/server/web/adapter.js:174:26)
    at (node_modules/next/dist/esm/server/async-storage/request-async-storage-wrapper.js:72:23)
    at (node_modules/next/dist/esm/server/web/adapter.js:161:46)
    at (node_modules/next/dist/compiled/@opentelemetry/api/index.js:1:7061) {
  stack: 'Error: atob() called with invalid base64-encoded data. (Only whitespace, \'+\', \'/\', alphanumeric ASCII, and up to two terminal \'=\' signs when the input data length is divisible by 4 are allowed.)\n    at (node_modules/jose/dist/browser/runtime/asn1.js:62:35)\n    at (node_modules/jose/dist/browser/runtime/asn1.js:123:11)\n    at (node_modules/jose/dist/browser/key/import.js:10:11)\n    at (app/lib/auth.ts:49:28)\n    at (middleware.ts:20:26)\n    at (middleware.ts:10:26)\n    at (node_modules/next/dist/esm/server/web/adapter.js:174:26)\n    at (node_modules/next/dist/esm/server/async-storage/request-async-storage-wrapper.js:72:23)\n    at (node_modules/next/dist/esm/server/web/adapter.js:161:46)\n    at (node_modules/next/dist/compiled/@opentelemetry/api/index.js:1:7061)',
  code: 5,
  name: 'InvalidCharacterError',
  message: 'atob() called with invalid base64-encoded data. (Only whitespace, \'+\', \'/\', alphanumeric ASCII, and up to two terminal \'=\' signs when the input data length is divisible by 4 are allowed.)'
}
Which would suggest that the browser version (not node) is correctly being used and it is working locally, but not in production on Vercel
Olive WarblerOP
My bad, I've included one dash too much in the public key and jumped to conclusions. Thank you very much for your help anyways!