next.jsserverlessvercelauthorization-header

Vercel Production Branch is stripping Authorization header on POST to Serverless Function API


Nothing special about the API but I have a serverless function POST API which expects an Authorization header to validate and then writes to a db.

For example:

     curl --location --request POST 'https://myserver.server.com/api/endpoint' \
        --header 'Authorization: Bearer blahblahblahblah'

In a Vercel Preview branch I'm able to get this to work and the Authorization header is passed to my API as expected. When I test this out in production the Authorization header is stripped from the request (figured that out by logging the raw request headers). What's are the difference between Preview and Production with respect to Authorization headers? What do I need to do to forward the header in Production?

Any help would be greatly appreciated. Thanks in advance!


Solution

  • This seems to be a bug in Vercel (Support is already notified) so let's wait for what they say. I'm assuming they consume the authorization header themselves and drop it afterward. It's a bit strange that this only happens in PROD but we shall see.

    Workaround

    Luckily, for us, this is quite easy to workaround. I've posted my updated function to illustrate the point. The main thing is to use any header other than authorization

    I'm using x_authorization, but the name is entirely arbitrary.

    export default async function handler(
      req: NextApiRequest,
      res: NextApiResponse
    ) {
      if (req.method === 'POST') {
        //using 'custom' x_authorization header because the regular 'authorization' header is stripped by Vercel in PROD environments.
        const { x_authorization } = req.headers
    
        if (x_authorization === `Bearer ${process.env.CRON_API_KEY}`) {
          
          //TODO: YOU DO YOUR THING HERE!!!
    
          res.status(200).json()
        } else {
          res.status(401).end()
        }
      } else {
        res.setHeader('Allow', 'POST')
        res.status(405).end('Method Not Allowed')
      }
    }