My Nextjs application using the same access token twice

My auth0.ts file

import { isPlatform } from ‘@/constants’;
import { platformApps } from ‘@/constants/enums/enums’;
import { Auth0Client } from ‘
/nextjs-auth0/server’;

import { NextResponse } from ‘next/server’;

export const getAuth0Client = (params?: any) => {
const auth0 = new Auth0Client({
enableAccessTokenEndpoint: false,
authorizationParameters: params
? params
: {
audience: process.env.AUTH0_AUDIENCE,
…(isPlatform && { connection: ‘XXXXXXX’ }),
},
onCallback: async (error, context, session) => {
  let errorCause = error?.cause?.toString();

  if (errorCause?.includes('OAuth2Error:')) {
    errorCause = errorCause.replace('OAuth2Error:', '');
  }

  if (errorCause && errorCause.includes('verify your email')) {
    //grab the email from error messages
    const emailRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/;
    const email = errorCause.match(emailRegex)?.[0];

    //if email exist append it to the url otherwise make it empty string
    const absoluteURL = `${process.env.AUTH0_BASE_URL}/verify-email-url`;
    return NextResponse.redirect(absoluteURL);
  } else if (error) {
    //if error in signinng, redirect to the error page
    const getPlatformLink = () => {
      if (process.env.NEXT_PUBLIC_PLATFORM === platformApps) {
        return `${process.env.AUTH0_BASE_URL}/error-url`;
      } else {
        return `${process.env.AUTH0_BASE_URL}/?authError=${errorCause}`;
      }
    };

    const absoluteURL = getLink();
    return NextResponse.redirect(absoluteURL);
  }
  let redirectUrl = process.env.AUTH0_BASE_URL;
  let returnToUrl = context?.returnTo === '/' ? null : context?.returnTo;

  return NextResponse.redirect(`${returnToUrl || redirectUrl}`);
},
});
return auth0;
};

My middleware.ts file

// import { auth0 } from '@/lib/auth0';
import { NextRequest, NextResponse } from 'next/server';
import { revalidateMyOrders } from './network/serverApis/creditCard';
import { protectedPages } from './constants/routes';
import { platformApps } from './constants/enums/enums';
import { i18nRouter } from 'next-i18n-router';
import { i18nConfig } from './i18n/i18nConfig';
import { getAuth0Client } from './lib/auth0';

const protectedRoutes: string[] = [
  
    ...protectedPages.filter(value => value.protected).map(value => value.href)
    
];

export default async function middleware(req: NextRequest) {
  const pathname = req.nextUrl.pathname;
  const absoluteUrlHub = `${process.env.AUTH0_BASE_URL}/login-url`;
  const absoluteURL =
    process.env.NEXT_PUBLIC__APP === platformApps
      ? absoluteUrlHub
      : `${process.env.AUTH0_BASE_URL}`;

  if (pathname.startsWith('/auth')) {
    let params;
    if (pathname === '/auth/login') {
      if (req.url.includes('sign-up-url')) {
        params = {
          audience: process.env.AUTH0_AUDIENCE,
          screen_hint: 'signup',
        };
      } else if (req.url.includes('url-1')) {
        params = {
          audience: process.env.AUTH0_AUDIENCE,
        };
      }
    }

    const auth0 = getAuth0Client(params);

    return await auth0.middleware(req);
  }

  const responsei18nMiddleware = i18nRouter(req, i18nConfig);
  if (pathname === '/url-2' || pathname === '/url-3') {
    const auth0 = getAuth0Client();

    // get the user
    const getUserSession = await auth0.getSession();

    // if the user exist redirect to homepage
    if (getUserSession) return NextResponse.redirect(absoluteURL.toString());
  }
  if (protectedRoutes.includes(pathname) || pathname.includes('/my-url')) {
    const auth0 = getAuth0Client();

    try {
      // get the user
      const getUserSession = await auth0.getSession();

      if (getUserSession) {
        let timeNow = Math.floor(Date.now() / 1000);

        // Note the difference is in seconds
        let diff = getUserSession.tokenSet.expiresAt - timeNow;

        if (diff <= Number(process.env.MIDDLEWARE_REFRESH_TOKEN_THRESHOLD || 300)) {
          // refreshing the token because in server components the token is not updated
          await auth0.getAccessToken(req, responsei18nMiddleware, {
            refresh: true,
          });
        }
      }

      // if the user does not exist redirect to unauthorized
      if (getUserSession === null) {
        return NextResponse.redirect(absoluteURL.toString());
      }
    } catch (error) {
      console.log('error getting user session: ', error);
    }
  }

  return responsei18nMiddleware;
}

export const config = {
  matcher: '/((?!api|static|.*\\..*|_next).*)',
};

I have been encountering issues that my application is using the same refresh token twice which invalidates the session and forces the user to logout. I haven’t able to produce the error but I still see it in logs.

I am using these packages:
auth0 sdk: “@auth0/nextjs-auth0”: “4.6.1”
NextJS version: 15.0.4

Any ideas from anyone?

Hi @huzaifa.murtaza

Welcome to the Auth0 Community!

I am sorry about the delayed reply to your inquiry!

Are you using Refresh Token Rotation for your application?
Also, could you let me know what is the exact error you are receiving in your logs regarding the refresh tokens?

From what I understand, your application might be reusing and old refresh token instead of retrieving a new one, thus logging out the user. Are you storing the token properly using localStorage or other option for the cache location?

Additionally, have you checked out the documentation for NextJS regarding using Refresh Tokens? You could also open an issue on SDK’s page for further insight/support if necessary!

If you have any other questions, let me know, I will be looking forward to your reply!

Kind Regards,
Nik

Hi again!

I see that you have not replied back regarding the matter. I will be marking the previous reply as a Solution, however, if you still need assistance, you can reply back or open a new topic referencing this one.

Kind Regards,
Nik