Reputation: 85
I have a need to add a header to each request to the server.
I do it this using _midleware like this:
export async function middleware(req: NextRequest): Promise<NextResponse> {
req.headers.append('x-custom-header', '1337');
return NextResponse.next();
}
If I do console.log(req.headers)
I see that the request header has been added:
BaseHeaders [Headers] {
[Symbol(map)]: {
accept: [ '*/*' ],
'accept-encoding': [ 'gzip, deflate, br' ],
'accept-language': [ 'en-GB,en-US;q=0.9,en;q=0.8' ],
'cache-control': [ 'no-cache' ],
connection: [ 'keep-alive' ],
cookie: ...,
host: ...,
pragma: [ 'no-cache' ],
referer: ...,
...,
'x-custom-header': [ '1337' ]
}
}
However, this does not modify the request: there is no request header in the browser.
Why is the request not modified? Are there alternative ways to modify request headers in Next.js?
Upvotes: 14
Views: 52496
Reputation: 909
Looks like starting from Next.js v13.0.0 it is now possible to modify request headers: https://nextjs.org/docs/advanced-features/middleware#setting-headers
Here's a code snippet from the documentation:
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
// Clone the request headers and set a new header `x-hello-from-middleware1`
const requestHeaders = new Headers(request.headers)
requestHeaders.set('x-hello-from-middleware1', 'hello')
// You can also set request headers in NextResponse.rewrite
const response = NextResponse.next({
request: {
// New request headers
headers: requestHeaders,
},
})
// Set a new response header `x-hello-from-middleware2`
response.headers.set('x-hello-from-middleware2', 'hello')
return response
}
Upvotes: 13
Reputation: 55
This is what worked for me. The header is changed in middleware and reflected in getServerSideProps.
export async function middleware(request: NextRequest) : Promise<NextResponse> {
const response = NextResponse.next()
response.headers.append("key", "value")
return response
}
//inside page
export const getServerSideProps = wrapper.getServerSideProps(store => async (context) => {
//the headers are changed here
console.log(context.res.getHeaders())
return {
props: {}
}
}
});
Upvotes: 3
Reputation: 29326
Interesting question actually, since although I've done a lot of work on SPA architectures I hadn't looked into nextjs and its SSR behavior.
CUSTOM HEADERS AND CROSS SITE REQUEST FORGERY
A good angle for solving your problem is to think about other common use cases for custom headers and look for a nextjs solution. A security related one is to send a Cross Site Request Forgery custom request header, eg example-csrf
, in data changing API requests.
When I searched for nextjs ways to do that I found this next-csrf library and I suspect it will enable you to solve your problem. From what I can see, it works like this, though I think you'll understand the nextjs specifics better than me:
The middleware class runs on the website when a request is first received, and creates the request header value
The value is then provided to React components, which will run in the browser:
import { getCsrfToken } from '../lib/csrf';
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} csrfToken={getCsrfToken()} />
}
const response = await fetch('/api/protected', {
'headers': {
'XSRF-TOKEN': csrfToken,
}
});
There are some issues / feedback posted on the CSRF GitHub repo also - reading some of those may help you with your own solution.
ARCHITECTURE THOUGHTS
It is interesting looking at this, since I know nextjs is highly respected and enables better SEO etc. It also reminds me of older website technologies where developers often struggled, due to having to switch between client side and server side code. Being in control of data requests is an important technical foundation.
Out of interest, at Curity we have some code resources focused on SPA security, CDN deployment and developer experience, in case any of this is ever useful, for future reference. We do not use SSR currently, but we may want to say more about SSR use cases in future:
Upvotes: 1
Reputation: 424
You can add custom headers in a similar way you would by adding security headers, by using headers
in your next.config.js
:
// next.config.js
// You can choose which headers to add to the list
// after learning more below.
const securityHeaders = []
module.exports = {
async headers() {
return [
{
// Apply these headers to all routes in your application.
source: '/:path*',
headers: securityHeaders,
},
]
},
}
Upvotes: -1