From a90fad59b4ab0990eb06931babbd242cad09537e Mon Sep 17 00:00:00 2001 From: Ayush Amawate Date: Fri, 26 Dec 2025 11:22:26 +0530 Subject: [PATCH] fix(backend): handle multiple token types in acceptsToken array Fixes token-type-mismatch error when using arrays in acceptsToken option. Previously, when acceptsToken was an array like ['session_token', 'api_key'], the code would always route to the machine token handler, causing session tokens to fail with token-type-mismatch errors. Now, when acceptsToken is an array, the function checks the actual token type and routes to the appropriate handler (session or machine). - Added routing logic for array acceptsToken values - Added tests for mixed token type arrays - Preserves backward compatibility with existing usage Fixes #7520 --- .changeset/fix-multiple-token-types-array.md | 5 +++ .../src/tokens/__tests__/request.test.ts | 32 +++++++++++++++++++ packages/backend/src/tokens/request.ts | 7 ++++ 3 files changed, 44 insertions(+) create mode 100644 .changeset/fix-multiple-token-types-array.md diff --git a/.changeset/fix-multiple-token-types-array.md b/.changeset/fix-multiple-token-types-array.md new file mode 100644 index 00000000000..db48bdbb5db --- /dev/null +++ b/.changeset/fix-multiple-token-types-array.md @@ -0,0 +1,5 @@ +--- +"@clerk/backend": patch +--- + +Fix token-type-mismatch error when using multiple `acceptsToken` values in `authenticateRequest`. When `acceptsToken` is an array containing both session and machine token types (e.g., `['session_token', 'api_key']`), the function now correctly routes to the appropriate authentication handler based on the actual token type, instead of always treating them as machine tokens. \ No newline at end of file diff --git a/packages/backend/src/tokens/__tests__/request.test.ts b/packages/backend/src/tokens/__tests__/request.test.ts index 0d140f8b093..54b2e775e01 100644 --- a/packages/backend/src/tokens/__tests__/request.test.ts +++ b/packages/backend/src/tokens/__tests__/request.test.ts @@ -1426,6 +1426,38 @@ describe('tokens.authenticateRequest(options)', () => { isAuthenticated: false, }); }); + + test('accepts session_token when it is in acceptsToken array with machine tokens', async () => { + server.use( + http.get('https://api.clerk.test/v1/jwks', () => { + return HttpResponse.json(mockJwks); + }), + ); + + const request = mockRequest({ authorization: `Bearer ${mockJwt}` }); + const requestState = await authenticateRequest( + request, + mockOptions({ acceptsToken: ['session_token', 'api_key'] }), + ); + + expect(requestState).toBeSignedIn(); + }); + + test('accepts api_key when it is in acceptsToken array with session_token', async () => { + server.use( + http.post(mockMachineAuthResponses.api_key.endpoint, () => { + return HttpResponse.json(mockVerificationResults.api_key); + }), + ); + + const request = mockRequest({ authorization: `Bearer ${mockTokens.api_key}` }); + const requestState = await authenticateRequest( + request, + mockOptions({ acceptsToken: ['session_token', 'api_key'] }), + ); + + expect(requestState).toBeMachineAuthenticated(); + }); }); describe('Token Location Validation', () => { diff --git a/packages/backend/src/tokens/request.ts b/packages/backend/src/tokens/request.ts index 0061828b026..6624c292205 100644 --- a/packages/backend/src/tokens/request.ts +++ b/packages/backend/src/tokens/request.ts @@ -788,6 +788,13 @@ export const authenticateRequest: AuthenticateRequest = (async ( if (acceptsToken === TokenType.SessionToken) { return authenticateRequestWithTokenInHeader(); } + // When acceptsToken is an array, route based on the actual token type + if (Array.isArray(acceptsToken)) { + if (isMachineToken(authenticateContext.tokenInHeader)) { + return authenticateMachineRequestWithTokenInHeader(); + } + return authenticateRequestWithTokenInHeader(); + } return authenticateMachineRequestWithTokenInHeader(); }