I’m using the NextJS App Router as a Backend-for-Frontend (BFF) pattern.
For authentication, I’m using the NextJS Auth0 library.
My frontend is a separate application written in React.
System Workflow:
The frontend calls /api/auth/login API in the BFF to initiate login.
The BFF calls handleLogin() of Auth0 and redirects back to the frontend once authenticated.
This process completes successfully, and I am able to log in.
Problem:
After logging in, I want to get the user session from the frontend to verify if the user is authenticated. However:
When fetching /api/session from the frontend, getSession() returns a null value.
When configuring the headers to address CORS issues, the API is not called and returns a CORS error.
Accessing /api/session directly from the browser returns the correct session value.
getSession() also returns a value when accessed from a page inside the BFF application.
It seems that Auth0 is not accepting API calls from external applications unless the call is made within the same application. However, I couldn’t find any documentation supporting this conclusion.
BFF Setup:
/api/auth/[auth0]/route.ts
`import { handleAuth, handleLogin, handleLogout } from '@auth0/nextjs-auth0'
export const GET = handleAuth({
login: handleLogin({
returnTo: 'http://localhost:8080'
}),
logout: handleLogout({ returnTo: process.env.AUTH0_BASE_URL + '/'}),
})
`
/api/session/route.ts
`export const GET = withApiAuthRequired(async () => {
const session = await getSession();
return new Response(JSON.stringify(session?.user));
})
`
Frontend Setup:
`import React, { useEffect, useState, type ReactElement } from 'react'
export default function Navigation (): ReactElement {
const userSession = async () => {
const profile = await fetch("http://localhost:3001/api/session", {
method: 'GET',
headers: {
"Content-Type" : "application/json",
// "Access-Control-Allow-Credentials" : "true", // If I enable these settings, it returns CORS error
// "Access-Control-Allow-Origin" : "http://localhost:8080"
},
// mode: 'cors',
// credentials: 'include',
}).then((response) => response.json());
}
return (
<div className="w-full h-14 pt-2 pb-14 px-3 border-b border-slate-400 flex flex-col justify-start items-end gap-3.5">
<div className="flex justify-start items-start">
<div className="w-46 h-12 px-10 py-3 bg-sky-600 rounded-lg flex justify-center items-center gap-1 ml-auto">
<a href='http://localhost:3001/api/auth/login'>LOGIN</a>
{/* <button onClick={userSession} className="text-center text-white text-base font-medium leading-normal tracking-wide" data-testid="ui-element-login">ログイン</button> */}
</div>
<div className="w-46 h-12 px-10 py-3 bg-sky-600 rounded-lg flex justify-center items-center gap-1 ml-auto">
<button onClick={userSession} className="text-center text-white text-base font-medium leading-normal tracking-wide" data-testid="ui-element-login">Get comment</button>
</div>
<div className="w-46 h-12 px-10 py-3 bg-sky-600 rounded-lg flex justify-center items-center gap-1 ml-auto">
<a href='http://localhost:3001/api/auth/logout'>LOGOUT</a>
{/* <button onClick={handleLogin} className="text-center text-white text-base font-medium leading-normal tracking-wide" data-testid="ui-element-login">ログイン</button> */}
</div>
</div>
</div>
)
}
`
This setup returns Unauthorized error
{error: ‘not_authenticated’, description: ‘The user does not have an active session or is not authenticated’}
And when I enabled the request headers, CORS error is displayed.
localhost/:1 Access to fetch at ‘http://localhost:3001/api/protected’ from origin ‘http://localhost:8080’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: The value of the ‘Access-Control-Allow-Credentials’ header in the response is ” which must be ‘true’ when the request’s credentials mode is ‘include’.
Is this approach feasible? How can I fetch the session data from an external app with Auth0? Does anyone have any idea or experience in making this work?