Replies: 6 comments 9 replies
-
Facing the same issue. |
Beta Was this translation helpful? Give feedback.
-
As mentioned above, we're having trouble adding the export default async function middleware(request: NextRequest) {
const nonce = Buffer.from(crypto.randomUUID()).toString('base64')
const cspHeader = `
default-src 'self';
script-src 'self' 'nonce-${nonce}' 'strict-dynamic';
style-src 'self' 'nonce-${nonce}';
img-src 'self' blob: data:;
font-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
block-all-mixed-content;
upgrade-insecure-requests;
`
// Replace newline characters and spaces
const contentSecurityPolicyHeaderValue = cspHeader
.replace(/\s{2,}/g, ' ')
.trim()
const requestHeaders = new Headers(request.headers)
requestHeaders.set('x-nonce', nonce)
requestHeaders.set(
'Content-Security-Policy',
contentSecurityPolicyHeaderValue
)
// Step 1: Use the incoming request (example)
const defaultLocale = request.headers.get('x-default-locale') || 'en';
// Step 2: Create and call the next-intl middleware (example)
const handleI18nRouting = createIntlMiddleware({
locales: ['en', 'de'],
defaultLocale,
localePrefix: "as-needed",
});
const response = handleI18nRouting(request);
// How can we add the `requestHeaders` with createIntlMiddleware ?
/*
const response = NextResponse.next({
request: {
headers: requestHeaders,
},
})
*/
// Step 3: Alter the response (example)
response.headers.set('x-default-locale', defaultLocale);
response.headers.set(
'Content-Security-Policy',
contentSecurityPolicyHeaderValue
)
return response;
}
export const config = {
matcher: ['/((?!api|_next|_vercel|.*\\..*).*)']
}; |
Beta Was this translation helpful? Give feedback.
-
I am having the same problem.. trying to solve for days... |
Beta Was this translation helpful? Give feedback.
-
The following is a working example of using next-intl with NextAuth and adding a // Compile a list of all locales
const allLocales = locales.concat(betaLocales)
const publicPages = ["/auth/login", "/auth/error", "/events/.*"]
// Configure next-intl middleware
const intlMiddleware = createIntlMiddleware({
locales: allLocales,
defaultLocale: "en-US",
localePrefix: "always",
})
const authMiddleware = withAuth(
function onSuccess(req) {
const response = intlMiddleware(req)
const csp = req.headers.get("Content-Security-Policy")
if (!csp) {
throw new Error("No CSP header found")
}
response.headers.set("Content-Security-Policy", csp)
return response
},
{
callbacks: {
authorized: ({ token }) => token !== null,
},
pages: {
signIn: "/auth/login",
signOut: "/",
error: "/auth/error",
},
},
)
export default function middleware(request: NextRequest) {
const publicPathnameRegex = RegExp(
`^(/(${locales.join("|")}))?(${publicPages.join("|")})/?$`,
"i",
)
const isPublicPage = publicPathnameRegex.test(request.nextUrl.pathname)
const nonce = Buffer.from(crypto.randomUUID()).toString("base64")
const cspWithNonce = csp(nonce) // Generate the CSP as described in the Next docs
const requestHeaders = new Headers(request.headers)
requestHeaders.set("x-nonce", nonce)
requestHeaders.set("Content-Security-Policy", cspWithNonce)
const req = new NextRequest(request, {
headers: requestHeaders,
})
// Handle the request with the appropriate middleware
let response: NextResponse
if (isPublicPage) {
response = intlMiddleware(req)
response.headers.set("Content-Security-Policy", cspWithNonce)
} else {
response = (authMiddleware as unknown as typeof intlMiddleware)(req)
}
return response
}
export const config = {
matcher: [
"/((?!_next/static|.well-known|fonts|icons|images|favicon.ico|apple-touch-icon.png|service-worker.js|version).*)",
],
} |
Beta Was this translation helpful? Give feedback.
-
I'm facing the same issue, please try this approach import { NextFetchEvent, NextRequest, NextResponse } from 'next/server';
import createIntlMiddleware from 'next-intl/middleware';
// Configuration for next-intl middleware
const intlMiddleware = createIntlMiddleware({
locales: ['en', 'ko'], // Add your supported locales
defaultLocale: 'en',
});
export async function middleware(request: NextRequest, event: NextFetchEvent) {
// Run next-intl middleware
const intlResponse = intlMiddleware(request);
// Generate nonce and set CSP headers
const nonce = Buffer.from(crypto.randomUUID()).toString('base64');
console.log('Generated Nonce:', nonce);
const cspHeader = `
default-src 'self';
script-src 'self' 'nonce-${nonce}' 'strict-dynamic';
style-src 'self' 'unsafe-inline';
img-src 'self' blob: data:;
font-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
upgrade-insecure-requests;
`;
const contentSecurityPolicyHeaderValue = cspHeader.replace(/\s{2,}/g, ' ').trim();
// Merge headers from both responses
const response = intlResponse || NextResponse.next();
response.headers.set('x-nonce', nonce);
response.headers.set('Content-Security-Policy', contentSecurityPolicyHeaderValue);
return response;
}
export const config = {
matcher: [
// Enable a redirect to a matching locale at the root
'/',
// Set a cookie to remember the previous locale for
// all requests that have a locale prefix
'/(en|ko)/:path*',
// Enable redirects that add missing locales
// (e.g. `/pathnames` -> `/en/pathnames`)
'/((?!api|_next|_vercel|.*\\..*).*)',
],
}; |
Beta Was this translation helpful? Give feedback.
-
There is a problem with the approach I posted above in that I think you can do this instead:
Edit: This is correct in @realrisman approach above |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
We'd like to implement Content Security Policy, but we're having trouble working out how to integrate it using Next-intl's custom middleware. Has anyone already done this?
Here's the Next documentation to add CSP:
Here's the next-intl middleware:
Beta Was this translation helpful? Give feedback.
All reactions