Next.js App Router (Auth0Client): getAccessToken returns encrypted JWE (alg: dir) instead of JWT (RS256) despite correct Audience

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:

  1. 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.

  2. 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
      },
    });
    
    
  3. 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) {
        // ...
      }
    }
    
    
  4. 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):

  1. Manual CURL Test (Success): If I request a token manually using client_credentials via 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.

  2. Browser Network Tab: When checking the /authorize request initiated by the Next.js app, I suspect the audience parameter 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:

  1. audience is set in authorizationParams.

  2. JWE is disabled in the API settings in the Dashboard.

  3. 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.

Hi @GuiEzz

Welcome to the Auth0 Community!

Can you try to go to the Auth0 Dashboard-> Settings (Tenant setting)-> API Authorization Settings-> Default Audience ->" Set it as same as your api audience“.

Let me know if this does the trick to you or not!

Kind Regards,
Nik

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.