Description
Describe the content issue:
I am highlighting this as a potential issue, although I am not 100% sure whether it's a bug or not.
This is the example given by the docs to handle middleware authentication in NextJS:
export async function middleware(request: NextRequest) {
const response = NextResponse.next();
const authenticated = await runWithAmplifyServerContext({
nextServerContext: { request, response },
operation: async (contextSpec) => {
try {
const session = await fetchAuthSession(contextSpec);
return (
session.tokens?.accessToken !== undefined &&
session.tokens?.idToken !== undefined
);
} catch (error) {
console.log(error);
return false;
}
}
});
if (authenticated) {
return response; // Response object is returned here
}
return NextResponse.redirect(new URL('/sign-in', request.url)); // Response object is not used here.
}
As you can see, the example creates a response
object which is used by runWithAmplifyServerContext
to set headers on the response. However, that response object is only returned where the user is authenticated. Shouldn't that response object be used to initialise NextResponse.redirect
too? What if the refresh token has expired or revoked? There might be set-cookie
headers that need to be passed to the browser.
Unless I misunderstand something, is the following not the better option?
export async function middleware(request: NextRequest) {
const response = NextResponse.next();
const authenticated = await runWithAmplifyServerContext({
nextServerContext: { request, response },
operation: async (contextSpec) => {
try {
const session = await fetchAuthSession(contextSpec);
return (
session.tokens?.accessToken !== undefined &&
session.tokens?.idToken !== undefined
);
} catch (error) {
console.log(error);
return false;
}
}
});
if (authenticated) {
return response;
}
// Use the response object to initialise the redirect
return NextResponse.redirect(new URL('/sign-in', request.url), response);
}
Again, unless I misunderstand something, this is even more important when you need to redirect authenticated users, because there is a high likelihood that the response contains set-cookie
headers.
export async function middleware(request: NextRequest) {
const response = NextResponse.next();
const authenticated = await runWithAmplifyServerContext({
nextServerContext: { request, response },
operation: async (contextSpec) => {
try {
const session = await fetchAuthSession(contextSpec);
return (
session.tokens?.accessToken !== undefined &&
session.tokens?.idToken !== undefined
);
} catch (error) {
console.log(error);
return false;
}
}
});
if (!authenticated) {
return response;
}
return NextResponse.redirect(new URL('/dashboard', request.url), response);
}
Is this correct? Should we be passing the response object to NextResponse.redirect
and NextResponse.rewrite
?
URL page where content issue is: https://docs.amplify.aws/gen1/javascript/build-a-backend/server-side-rendering/nextjs/#manage-auth-session-with-the-nextjs-middleware