问题
Being a newbie in Nodejs, I jumped right into writing a simple app without really reading up on good security practices. I just found out that using bodyParser()
for all routes is actually a bad thing because it allows for DOS attack using multipart files.
A recommended fix is to only load specific modules depending on the route. ie, for multipart fileupload, use multipart
. For regular POST without file uploads (ie, text form submission), use express.json(), express.urlencoded()
.
Or another option is to use busboy with connect-busboy. But the thing I'm confused on is how I can specify which route should handle multipart data and which should not? Otherwise, wouldn't I have the same problem as with bodyParser
?
Furthermore, busboy
docs says it does not handle GET
:
If you find that req.busboy is not defined in your code when you expect it to be, check that the following conditions are met. If they are not, req.busboy won't be defined:
1. The request method is not GET or HEAD
So, I'm even more confused how I would parse params
in a GET
. I think bodyParser
does this for me so I could access data with req.params
.
For example, how would I migrate away from bodyParser()
to busboy/connect-busboy
with this simple app:
var express = require('express');
var app = express();
var http = require('http').Server(app);
var bodyParser = require('body-parser');
app.use(bodyParser.json());
var busboy = require('connect-busboy');
app.use(busboy());
// How to use busboy to prevent multipart files here?
app.post("/form_data_no_fileupload", function(req, res) {
var somedata = req.body.somedata;
});
// Use busboy to handle both regular form data + fileuploads
app.post("/form_data_AND_fileupload", function(req, res) {
});
// What would handle GET without bodyparser?
app.get("/get_something", function(req, res) {
var params = req.params;
});
http.listen(3000, function() {});
回答1:
[How] I can specify which route should handle multipart data and which should not?
All of Express' routing methods allow for providing middleware specific to the route. This includes Router methods.
app.METHOD(path, callback [, callback ...])
Depending on the body expected for an individual route, you can use different modules to handle each of them (rather than applying them to the entire application with app.use()
).
var express = require('express');
var app = express();
var http = require('http').Server(app);
var bodyParser = require('body-parser');
var busboy = require('connect-busboy');
app.post("/form_data_no_fileupload",
bodyParser.urlencoded(),
function(req, res, next) {
// check that the request's body was as expected
if (!req.body) return next('route'); // or next(new Error('...'));
// ...
});
app.post("/form_data_AND_fileupload",
busboy({
limits: {
fileSize: 10 * 1024 * 1024
}
}),
function(req, res, next) {
// check that the request's body was as expected
if (!req.busboy) return next('route'); // or next(new Error('...'));
// ...
});
// ...
Furthermore, busboy docs says it does not handle GET.
So, I'm even more confused how I would parse
params
in aGET
.
Busboy and BodyParser are designed for reading in and parsing the request's body, which GET and HEAD requests aren't expected to have.
For such requests, parameters can only be passed within the query-string within the URL, which Express parses itself. They're available via req.query.
app.get('/get_something', function () {
console.log(req.originalUrl);
// "/get_something?id=1
console.log(req.query);
// { id: "1" }
});
req.params represents any placeholders matched in the path by the route. These are available for any route, regardless of the method.
app.get('/thing/:id', function (req, res) {
console.log(req.originalUrl);
// "/thing/2"
console.log(req.params);
// { id: "2" }
});
来源:https://stackoverflow.com/questions/29594399/migrating-away-from-bodyparser-in-express-app-with-busboy