Closed rhmnaulia closed 7 months ago
Hi @rhmnaulia, could you please share an example of what you are doing on CodeSandbox/in a repo? I am wondering if you are using the Matcher in your middleware file? If you are, it would opt the middleware completely out of running on certain routes and so your CSP logic would never run. If this is not the case for you, then there could be something else at play! Thanks.
Hello @rexfordessilfie, I'm not using Matcher. If you see, I have added console.log there and the console is printed. However, the CSP logic won't run and the header won't set.
Thanks for your response! I took a deeper look at your issue, and I was able to reproduce and resolve it locally.
Here's what I think is going on:
withAuth
to wrap your middleware means that the middleware logic does not execute if there is no authenticated user, hence your middleware CSP logic is never executed (your middleware response headers never make it back to the browser).pages
configuration, hence why you get back the home page - albeit without your CSP since again the CSP middleware logic is never executed.If you can afford to have your authentication pages (pages.signIn
, pages.signOut
etc) without CSP, then your current setup may work just fine.
If you do want CSP headers (or any other kind of headers) on every single page (while still enforcing authentication) you would have to apply withAuth
differently. Specifically, you can do something such as this:
export async function middleware(request: NextRequestWithAuth) {
console.log("Middleware executing!");
// Prepare the CSP headers
const { csp, nonce } = generateCsp();
const requestHeaders = new Headers(request.headers);
requestHeaders.set("x-nonce", nonce);
requestHeaders.set("content-security-policy", csp);
// Execute the NextAuth middleware which either returns a redirect response or nothing, if authentication
// was not required. See source for more: https://github.com/nextauthjs/next-auth/blob/v4/packages/next-auth/src/next/middleware.ts#L99
// If a redirect was returned, use it. Otherwise continue the response normally with NextResponse.next().
// Omitting the config here, but you can still include it (i.e withAuth(request, { pages: ... }))
const response = (await withAuth(request)) || NextResponse.next();
// Set the CSP headers on the response
requestHeaders.forEach((value, key) => {
response.headers.append(key, value);
});
console.log("Middleware executed!");
return response;
}
withAuth
on all routes (as you have in your issue) as well as in the solution above, means that even static assets (e.g a logo) cannot be accessed without an authenticated user. You could solve this by introducing some kind of matching logic to exclude such static assets, or any others which you would not want to be blocked by authentication."Refused to send form data to 'http://localhost:3000/api/auth/signin/github' because it violates the following Content Security Policy directive: "form-action 'self'". " Refused to load the image 'https://authjs.dev/img/providers/github.svg' because it violates the following Content Security Policy directive: "img-src 'self' data:".
The first one essentially breaks next-auth's in-built authentication but hopefully you have an alternate CSP-safe approach for getting static assets and handling sign-in/out's!
It looks like this issue did not receive any activity for 60 days. It will be closed in 7 days if no further activity occurs. If you think your issue is still relevant, commenting will keep it open. Thanks!
@rexfordessilfie rexfordessilfie
This is awesome! Thanks so much for your clear example and awesome project!
Question 💬
I'm facing an issue while trying to set the Content-Security-Policy header within my Next.js middleware. It works perfectly when I use the middleware without withAuth, and the headers are successfully set. However, when I wrap it with withAuth, the header doesn't get set. I've checked the documentation, but couldn't find much information about it.
How to reproduce ☕️
Use the code within the
withAuth
wrapper.Contributing 🙌🏽
No, I am afraid I cannot help regarding this