JoeWemyss
JoeWemyss

Reputation: 607

Strip specific query parameters in express

I am having some difficulty in stripping specific query parameters from a request in express. The issue is that in the normal flow, the user would fetch a Bearer Token from a third party which would then be sent to my REST API with each request. The token is decoded and the id of the user is added to the request.

I would like to be able to attach the ID of the user as a query parameter while in development mode, so that I can test the API using something like cURL or Postman, without having to write some sort of script to fetch a token every time.

To that end, I created a separate middleware to be used in development that would take the ID from the querystring, strip it out, and redirect to the new URL. I modified this answer to do so.

this.app.use((req, res, next) => {
    const id = req.query.id;
    req.user = { id };
    let basePath = url.parse(req.url).pathname;
    const queryKeys = Object.keys(req.query);
    if(queryKeys.length === 0) return res.status(400).send('no id attached');
    if(queryKeys.length === 1 && queryKeys[0] === 'id') return next();
    basePath += '?';
    queryKeys.forEach(queryKey => {
       if(basePath[basePath.length -1] !== '?') basePath += '&';
       if(queryKey !== 'id') basePath += `${queryKey}=${req.query[queryKey]}`
    });
    return res.redirect(basePath);
})

This function works fine if I test it using just the ID parameter, (say: http://localhost:5000/api/?id=someid) but if I add a second parameter(say: http://localhost:5000/api/?id=someid&skip=1), I get a 404 with the message / is not a recognized path.. From console.log() statements I can see that in the second example, res.redirect() is being called with /?skip=1, as expected.

What am I doing wrong?

Upvotes: 1

Views: 3223

Answers (1)

bpedro
bpedro

Reputation: 514

I'm not sure I understand what you're trying to do as it seems that you're redirecting to the same URL without the id query parameter, which would return a 400 error.

In any case, please take a look at this code snippet that correctly removes the id query parameter and does the redirection.

const url = require('url');
app.use((req, res, next) => {
  // return early if the id query parameter is not present
  if (!req.query.id) {
    return res.status(400).send('No id attached.');
  }

  // rebuild URL by removing the id query parameter
  const baseUrl = url.format({
    protocol: req.protocol,
    host: req.get('host'),
  });
  const myUrl = new url.URL(req.originalUrl, baseUrl);
  myUrl.searchParams.delete('id');
  const cleanUrl = `${myUrl.pathname}${myUrl.search}`;

  // redirecting to the URL without the id parameter will return a 400
  return res.redirect(cleanUrl);
});

You can easily adapt the code by using the cleanUrl variable so that, instead of redirecting to it, you could take some different action.

Let me know how it goes.

Upvotes: 1

Related Questions