aws-amplify / aws-amplify/docs
Middleware example does not always handle the response object
- Dominant language
- MDX
- Stars
- 506
- Forks
- 1.1k
- Avg merge
- 3h 14m
- Merged PRs (30d)
- 1
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:
```typescript
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?
```typescript
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.
```typescript
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
Contributor guide
Research direction
Start with the linked Next.js middleware documentation page and review the example's use of NextResponse.next, redirect, and rewrite alongside the response headers set by runWithAmplifyServerContext. Confirm the correct response-handling behavior, then update the example and explanatory text so authenticated and redirected flows preserve any required headers.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- next.js, typescript
- Domain
- authentication, documentation
- Issue type
- Documentation
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100