Custom Claims not showing up in NextJS Session

I’m trying to get custom claims to show up in my application and I’m having issue. I’ve read through several other topics with people have the same issue, but nothing I’ve tried so far has worked.

Below I’ve replaced my app URL with app.mysite.com

Here is my post-login action:

exports.onExecutePostLogin = async (event, api) => {
  api.idToken.setCustomClaim('https://app.mysite.com/test', 'hello-test');
  api.accessToken.setCustomClaim('https://app.mysite.com/access-test', 'hello-access-token-test');

  if (event.authorization) {
    api.idToken.setCustomClaim('https://app.mysite.com/roles', event.authorization.roles);
  }
};

and here is my auth0.ts library setup:

import { Auth0Client } from "@auth0/nextjs-auth0/server";

// Initialize the Auth0 client 
export const auth0 = new Auth0Client({
  // Options are loaded from environment variables by default
  // Ensure necessary environment variables are properly set
  // domain: process.env.AUTH0_DOMAIN,
  // clientId: process.env.AUTH0_CLIENT_ID,
  // clientSecret: process.env.AUTH0_CLIENT_SECRET,
  // appBaseUrl: process.env.APP_BASE_URL,
  // secret: process.env.AUTH0_SECRET,

  authorizationParameters: {
    // In v4, the AUTH0_SCOPE and AUTH0_AUDIENCE environment variables for API authorized applications are no longer automatically picked up by the SDK.
    // Instead, we need to provide the values explicitly.
    scope: process.env.AUTH0_SCOPE,
    audience: process.env.AUTH0_AUDIENCE,
  }
});

and environment variables with the sensitive information redacted

AUTH0_SECRET='SECRET'
APP_BASE_URL='http://localhost:3000'
AUTH0_DOMAIN='https://mysite.us.auth0.com'
AUTH0_CLIENT_ID='CLIENT_ID'
AUTH0_CLIENT_SECRET='CLIENT_SECRET'
AUTH0_AUDIENCE='https://mysite.us.auth0.com/api/v2/'
AUTH0_SCOPE='openid profile'

Here is my NextJS Auth0 setup where I’m trying to read it

export async function middleware(request: NextRequest) {
    const auth0Response: NextResponse = await auth0.middleware(request);

    const session = await auth0.getSession(request);
    console.log("Session:", session);
    // Session doesn't include the above claims

    ...

For good measure, I also check in a server side component to see if it showed up there, but it didn’t

import React from 'react';

import { auth0 } from '../lib/auth0';

export default async function Page() {
    const session = await auth0.getSession();
    console.log("Session in LawFirmsListPage:", session);
    ....

I’ve confirmed:

  • The action is deployed
  • The action is in the post-login trigger and it is saved
  • I’ve tried logging out and logging back in again before checking the claims
  • I’ve also tried going incognito and had the same issue

Hi @jasonminor

Welcome to the Auth0 Community!

I am sorry about the delayed response to your inquiry!

In the meantime, could you try the following code and let me know if it fixes the issue?

import { Auth0Client } from "@auth0/nextjs-auth0/server";

export const auth0 = new Auth0Client({
  async beforeSessionSaved(session, idToken) {
    return session;
  }
});

As far as I know, you have to configure the client to save the additional claims to the session, otherwise they will be filtered out since they are not part of the default claims.

I will come back as soon as possible with further details regarding the matter! If you have any other questions or further updates, let me know!

Kind Regards,
Nik

Hi @nik.baleca,

I added that code and it worked great! I can see all my custom claims now. Thanks!

For my own reference, how does that code you’ve pasted save additional claims to the session?

Hi @jasonminor, are you able to see the claims after a token refresh?
I’m experiencing a similar issue: I can see the custom claims after login, but when I call getAccessToken() to refresh the token once it expires, the new access token doesn’t contain any claims.

Hey @Rama, my situation might be unique because I’m reading these custom claims off the session variable, not from the token. I haven’t looked into reading custom claims from the token yet, but maybe there is a similar function like beforeTokenSaved or something similar that might do this?

Hi again!

To answer your question @jasonminor, this information can be found in our documentation regarding NextJS’s beforeSessionSaved hook. To save you some time, basically the hook is run right before the session is persisted. It helps modify the session claims before persisting them.

The session.user object passed to the beforeSessionSaved hook will contain every claim in the ID Token, including custom claims. You can use the filterDefaultIdTokenClaims utility to filter out the standard claims and only keep the custom claims you want to persist. The code provided above allows you to use the entire session.user object if you would like to include every claim in the ID Token. Alternatively, have you tried using the useUser() hook in order to see if the custom claims set by the actions are visible?

Otherwise @Rama, I will be addressing your issue in the post you have created regarding the matter as soon as possible!

Kind Regards,
Nik