clerk/javascript

[Node SDK]: Failed to resolve JWK during verification

shadoworion opened this issue · 6 comments

Preliminary Checks

Reproduction

https://github.com/shadoworion/clerk-key-bug/

Publishable key

sk_test_OnLZgum8iw2tRMVU7yYRAn8BotWNxI1F79COWJYWbU

Description

Steps to reproduce:

import { clerkClient } from "@clerk/clerk-sdk-node";
  
export const clerkAuth = async (token: string | null) => {
  try {
    return !!token ? clerkClient.verifyToken(token, {}) : null;
  } catch (error) {
    console.error(error);
    return null;
  }
};

Expected behavior:

Auto resolve JWK via network

Actual behavior:

ERR 28 |   constructor({
29 |     action,
30 |     message,
31 |     reason
32 |   }) {
33 |     super(message);
         ^
error: Failed to resolve JWK during verification.
      at new _TokenVerificationError (/backend/node_modules/@clerk/backend/dist/chunk-3ARITHGE.mjs:33:5)
      at /backend/node_modules/@clerk/backend/dist/chunk-R7QRZ6J6.mjs:1867:11
      at verifyToken (/backend/node_modules/@clerk/backend/dist/chunk-R7QRZ6J6.mjs:1851:28)
      at /backend/node_modules/@clerk/backend/dist/chunk-P263NW7Z.mjs:4:36
      at /backend/node_modules/@clerk/backend/dist/chunk-P263NW7Z.mjs:3:10
      at /backend/src/authentication/clerk.ts:12:14

OR

_TokenVerificationError: Failed to resolve JWK during verification.
    at verifyToken (/backend/node_modules/@clerk/backend/src/tokens/verify.ts:36:11)
    at Proxy. (/backend/node_modules/@clerk/backend/src/jwt/legacyReturn.ts:6:36)
    at clerkAuth (/backend/src/authentication/clerk.ts:14:10)
    at Object.context (/backend/src/server.ts:93:13)
    at onContextBuilding (/backend/node_modules/@envelop/core/cjs/plugins/use-extend-context.js:6:24)
    at Object.contextFactory (/backend/node_modules/@envelop/core/cjs/orchestrator.js:206:45)
    at processRequest (/backend/node_modules/graphql-yoga/cjs/process-request.js:46:26)
    at YogaServer.getResultForParams (/backend/node_modules/graphql-yoga/cjs/server.js:282:26)
    at handle (/backend/node_modules/graphql-yoga/cjs/server.js:352:25) {
  reason: 'jwk-failed-to-resolve',
  action: 'Set the CLERK_JWT_KEY environment variable.'
}

Environment

System:
    OS: macOS 14.4.1
    CPU: (11) arm64 Apple M3 Pro
    Memory: 991.89 MB / 18.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.10.0 - /usr/local/bin/node
    Yarn: 1.22.22 - /usr/local/bin/yarn
    npm: 10.2.5 - /usr/local/bin/npm
    bun: 1.1.6 - ~/.bun/bin/bun
  Browsers:
    Chrome: 124.0.6367.92
    Edge: 124.0.2478.67
    Safari: 17.4.1
  npmPackages:
    @clerk/clerk-sdk-node: 5.0.2 => 5.0.2 
    @graphql-yoga/plugin-response-cache: 3.5.0 => 3.5.0 
    @pothos/core: 3.41.1 => 3.41.1 
    @pothos/plugin-dataloader: 3.18.1 => 3.18.1 
    @pothos/plugin-prisma: 3.65.1 => 3.65.1 
    @prisma/client: 5.13.0 => 5.13.0 
    @types/uuid: 9.0.8 => 9.0.8 
    @whatwg-node/server-plugin-cookies: 1.0.2 => 1.0.2 
    bun-types: latest => 1.1.6 
    dataloader: 2.2.2 => 2.2.2 
    dayjs: 1.11.11 => 1.11.11 
    graphql: 16.8.1 => 16.8.1 
    graphql-middleware: 6.1.35 => 6.1.35 
    graphql-scalars: 1.23.0 => 1.23.0 
    graphql-shield: 7.6.5 => 7.6.5 
    graphql-yoga: 5.3.0 => 5.3.0 
    knex: 3.1.0 => 3.1.0 
    pg: 8.11.5 => 8.11.5 
    prisma: 5.13.0 => 5.13.0 
    uuid: 9.0.1 => 9.0.1

There is a problem with env "CLERK_SECRET_KEY".
If I add it manually, it works:

import { clerkClient } from "@clerk/clerk-sdk-node";

export const clerkAuth = async (token: string | null) => {
  try {
    return !!token ? clerkClient.verifyToken(token, { secretKey: String(process.env["CLERK_SECRET_KEY"]) }) : null;
  } catch (error) {
    console.error(error);
    return null;
  }
};

Hi!

Sorry to hear you're running into an issue. To help us best begin debugging the underlying cause, it is incredibly helpful if you're able to create a minimal reproduction. This is a simplified example of the issue that makes it clear and obvious what the issue is and how we can begin to debug it.

If you're up for it, we'd very much appreciate if you could provide a minimal reproduction and we'll be able to take another look.

Thanks for using Clerk!

I see that If I define global client it doesn't work in "verifyToken"

import { createClerkClient } from "@clerk/clerk-sdk-node";

export const clerkClient = createClerkClient({
  secretKey: String(process.env["CLERK_SECRET_KEY"]),
});

export const clerkAuth = async (token: string | null) => {
  try {
    return !!token ? clerkClient.verifyToken(token, {}) : null;
  } catch (error) {
    console.error(error);
    return null;
  }
};

Hey @shadoworion could you try installing this, and verify is the fix works for you ?

npm i @clerk/clerk-sdk-node@5.0.4-snapshot.v9a7208b --save-exact

@panteliselef
Hi, yes, it works now!

Can you also change "options" argument to optional?
(property) verifyToken: (token: string, options: VerifyTokenOptions) => Promise<any>

There is no need to add this empty object every time