admin管理员组

文章数量:1189403

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?

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?

Share Improve this question asked Feb 8, 2022 at 15:53 aiwaiw 851 gold badge2 silver badges7 bronze badges 15
  • Request is already sent right. They are modified before reaching your API code. Chrome will not know of it – Tushar Shahi Commented Feb 8, 2022 at 16:00
  • Please provide a MRE - stackoverflow.com/help/minimal-reproducible-example. – Ramakay Commented Feb 8, 2022 at 17:02
  • I found some discussions on this topic, maybe it will be useful: Modify request objects within middleware function and Add support for middleware rewrite proxy headers – aiw Commented Feb 14, 2022 at 14:12
  • 1 @PaulS. Same thing. I assume you want to send tokens for api requests. I solved a similar problem a little dirty, but simple by putting data in a cookie, which automatically goes into the headers of outgoing requests. Perhaps this compromise will suit you as well. Otherwise, I couldn't think of anything other than interceptors for fetch queries or fetcher function wrapper which will add the necessary headings to each query. – aiw Commented Feb 14, 2022 at 15:39
  • 1 So you want to change the headers of the incoming request before it hits the destination endpoint in your server, is that it? – fast-reflexes Commented Feb 16, 2022 at 4:03
 |  Show 10 more comments

4 Answers 4

Reset to default 13

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
}

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: {}
    }
  }
});

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()} />
}
  • Also I think the React views you write can then send that value from the browser if required:
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:

  • Sending CSRF headers
  • Token handler pattern code example

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,
      },
    ]
  },
}

本文标签: javascriptHow to modify request headers in NextjsStack Overflow