Hi everyone,
I am facing a persistent issue integrating a Next.js 15+ (App Router) frontend with a Python (FastAPI) backend.
The Problem: Even though I have configured the audience correctly in my Auth0Client instantiation, the auth0.getAccessToken() method in my Next.js API route returns an encrypted token (alg: dir, JWE) instead of the expected signed JWT (alg: RS256).
My Python backend rejects this token because it expects a standard RS256 Access Token to validate against the JWKS.
My Stack:
-
SDK:
@auth0/nextjs-auth0(Latest version using App Router setup) -
Frontend: Next.js 15 (App Router)
-
Backend: Python / FastAPI
-
Flow: Authorization Code Flow
Configuration:
-
Dashboard Settings:
-
API Identifier:
https://vision-api -
Signing Algorithm:
RS256 -
JSON Web Encryption (JWE): Disabled (I double-checked this).
-
Application (M2M) is authorized for this API.
-
-
Next.js Implementation (
src/lib/auth0.ts): I am instantiating the client manually to use in the App Router:TypeScript
import { Auth0Client } from "@auth0/nextjs-auth0/server"; export const auth0 = new Auth0Client({ // domain, clientID, secret are loaded from env authorizationParams: { scope: 'openid profile email offline_access', audience: 'https://vision-api', // <--- Explicitly set here }, }); -
The Proxy Route (
src/app/api/proxy/route.ts):TypeScript
import { auth0 } from '@/lib/auth0'; export async function GET(req: NextRequest) { try { const tokenResponse = await auth0.getAccessToken(); const accessToken = tokenResponse.accessToken || tokenResponse.token; // DEBUG LOGGING console.log("Token Header:", decodeHeader(accessToken)); // OUTPUT: { "alg": "dir", "enc": "A256GCM", ... } -> THIS IS THE ISSUE } catch (error) { // ... } } -
The Auth Route (
src/app/api/auth/[auth0]/route.ts):TypeScript
import { auth0 } from '@/lib/auth0'; export const GET = auth0.handleAuth();
What I have verified (Debugging):
-
Manual CURL Test (Success): If I request a token manually using
client_credentialsvia terminal:Bash
curl --request POST --url ... --data '{"audience":"https://vision-api", ...}'I receive a correct RS256 JWT. I can pass this token to my Python backend and it works perfectly (HTTP 200). This proves the API and Auth0 Dashboard configuration are correct.
-
Browser Network Tab: When checking the
/authorizerequest initiated by the Next.js app, I suspect theaudienceparameter might not be passing through correctly, causing Auth0 to issue an opaque/encrypted session token instead of an API Access Token.
The Question: Why does @auth0/nextjs-auth0 return an opaque/encrypted JWE (alg: dir) even when:
-
audienceis set inauthorizationParams. -
JWE is disabled in the API settings in the Dashboard.
-
I am requesting a token for a Custom API.
How can I force the SDK to retrieve the decrypted RS256 Access Token so I can pass it to my external backend?
Any help is appreciated.