Sam
Sam

Reputation: 855

How to read custom header in CORS middleware

I have created CORS middleware using CORS package. This middleware will be called before each call. Here is my implementation.

const corsMiddleware = async (req, callback) => {
  const { userid } = req.headers|| req.cookies {};
  let whiteList = await getWhiteListDomains(userid)
  return callback(null, {
    origin: whiteList,
    credentials: true,
    allowedHeaders: ["userid", "authorization", "content-type"]
  });
};

And added this middleware before route initialization as

app.use(cors(corsMiddleware));
app.options("*", cors(corsMiddleware));



app.get("/user", (req, res, next)=>{
    // code
})

From Browser I am trying to call the API as

axios({ method: "get", url: "http://localhost:3000/user", headers: {userId:"1234"} });

While debugging on the server I see

access-control-request-headers:"userid"

in the headers of the request object.

I am not able to read the custom header. This might be happening because I am trying to read the custom header before CORS initialization. But still, I want to read that custom header.

Upvotes: 2

Views: 399

Answers (2)

Boris Cissoko
Boris Cissoko

Reputation: 31

you must parse your request

try this npm i body-parser

and

const bodyParser = require('body-parser');
app.use(bodyParser.json())

Upvotes: 0

Dez
Dez

Reputation: 5838

You have mainly two problems in your code.

First one, and easier to solve is that you are missing access-control-allow-origin in the option that sets the Access-Control-Allow-Headers:

return callback(null, {
  origin: whiteList,
  credentials: true,
  allowedHeaders: [
    "access-control-allow-origin",
    "authorization",
    "content-type",
    "userid"
  ]
});

The second one is the most important because it is related to how CORS works. This problem you are having is that CORS is already rejecting the petition in the pre-flight OPTIONS request. It never allows the browser to execute the GET request.

You say that you want to read the custom header userId in the pre-flight OPTIONS request but you can't. The reason is because the pre-flight OPTIONS request is created by the browser automatically and it won't use the custom headers you are setting up in the Axios call. It will only send these headers for the CORS:

Origin // URL that makes the request
Access-Control-Request-Method // Method of the request is going to be executed 
Access-Control-Request-Headers // Headers allowed in the request to be executed

Because your custom header is not being sent so in the pre-flight OPTIONS when you try to access the value of userId, you get an undefined value:

const { userid } = req.headers|| req.cookies;
console.log(userid); // undefined

And because you are using that value that is not matching in your async function getWhiteListDomains probably getting another undefined, the value set up in the origin option of the CORS middleware is undefined that provokes the CORS middleware rejects the pre-flight OPTIONS request.

let whiteList = await getWhiteListDomains(userid); // userid === undefined
console.log(whitelist); // undefined
return callback(null, {
  origin: whiteList, // undefined
  credentials: true,
  allowedHeaders: ["userid", "authorization", "content-type"]
});

I am not totally sure which is your goal trying to use your custom header as CORS check, but my advise would be when dealing with customised CORS configuration to only check the Origin header because that's its purpose: to limit and control which URLs can access to your server and resources.

If you are interested in creating any kind of authorisation or limited by user implementation in the requests received by your server, I suggest you to use a different custom middleware and not involve CORS at all like you are trying now.

Upvotes: 4

Related Questions