Reputation: 607
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
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