每当我将enctype =“multipart / form-data”添加到我的html表单时,我会得到ForbiddenError: invalid csrf token
如果我删除了enctype,它可以正常工作
我发送的csrf代码如下:input(type="hidden" name="_csrf" value= csrf_token)
我的快递文件:
var express = require('express');
var session = require('express-session');
var compression = require('compression');
var cookieParser = require('cookie-parser');
var cookieSession = require('cookie-session');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var csrf = require('csurf');
var env = process.env.NODE_ENV || 'development';
module.exports = function (app, passport) {
// Compression middleware (should be placed before express.static)
app.use(compression({
threshold: 512
}));
// Static files middleware
app.use(express.static(config.root + '/public'));
// set views path and default layout
app.set('views', config.root + '/app/views');
app.set('view engine', 'jade');
// bodyParser should be above methodOverride
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
app.use(methodOverride(function (req, res) {
if (req.body && typeof req.body === 'object' && '_method' in req.body) {
// look in urlencoded POST bodies and delete it
var method = req.body._method;
delete req.body._method;
return method;
}
}));
// cookieParser should be above session
app.use(cookieParser());
app.use(cookieSession({ secret: 'secret' }));
app.use(session({
secret: pkg.name,
proxy: true,
resave: true,
saveUninitialized: true,
store: new mongoStore({
url: config.db,
collection : 'sessions'
})
}));
// use passport session
app.use(passport.initialize());
app.use(passport.session());
// connect flash for flash messages - should be declared after sessions
// adds CSRF support
if (process.env.NODE_ENV !== 'test') {
app.use(csrf());
app.use(function(req, res, next){
res.locals.csrf_token = req.csrfToken();
next();
});
}
};
我的表格:
form(action="/adminfruta/criarproduto" enctype="multipart/form-data" method="post")
input(type="hidden" name="_csrf" value= csrf_token)
.tipo Tipo do Produto
input(type="radio", value="cesta", name="type", id="cesta", checked="checked")
label.radio(for="cesta") Cesta
input(type="radio", value="avulso", name="type", id="avulso")
label.radio(for="avulso") Avulso
label(for="name") Nome do Produto:
input(type="text" name="name" id="name")
label(for="code") Código da Cesta no sistema
input(type="text" name="code" id="code")
label(for="inventory") Estoque:
input(type="number" name="inventory")
label(for="description") Descrição:
//- textarea#description(name="description")
select(multiple="multiple" name="description" id="descricao")
for item in itens
option(value= item.id)= item.name
label(for="quantities") Quantidade de cada item, de acordo com a ordem da lista (não da ordem que você selecionou) separado por virgulas
input(type="text" name="quantities" id="quantities" placeholder="Exemplo: 3,1,1,4,2,6")
.fotos
.half
//- .pic
//- img(src="/img/produto.png", alt="")
.choose Escolha foto 1 (tamanho 250x250 px):
input(type="file" name="foto1")
.half
//- .pic
//- img(src="/img/produto.png", alt="")
.choose Escolha foto 2 (tamanho 250x250 px):
input(type="file" name="foto2")
.fotos
.half
label(for="price") Preço(em centavos):
input(type="number" name="price" placeholder="R$86,00 ficaria 8600")
.half
label(for="discount") Desconto (opcional):
input(type="number" name="discount")
.tipo Categorias:
ul.categories
for category in categories
li
input(type="radio" value= category.id id= category.name name="category")
label(for= category.name) #{category.name}
.tipo Produtos Relacionados:
.relations
select(id="related_products" name="related_products" multiple="multiple")
for product in products
option(value= product.id)= product.name
.tipo Adicionais:
.relations
select(id="addons" name="addons" multiple="multiple")
for item in itens
option(value= item.id) #{item.name}
button.button.save(type="submit") Criar Novo
我的路线档案
var mongoose = require('mongoose');
var admin = require('admin');
var aws = require('aws-sdk');
var multer= require('multer');
var multerS3 = require('multer-s3');
var s3 = new aws.S3({/*params: {Bucket: 'frutacor'}*/});
// var upload = multer({ dest: 'public/img/users/' });
var upload = multer({
storage: multerS3({
s3: s3,
bucket: 'frutacor',
acl: 'public-read',
key: function (req, file, cb) {
cb(null, Date.now().toString());
}
})
});
module.exports = function (app, passport) {
app.post('/adminfruta/criarproduto', admin.verifyAdmin, upload.fields([
{name: 'foto1', maxCount: 1},
{name: 'foto2', maxCount: 1}]), admin.createProduct);
}
最后是admin.js文件
exports.createProduct = function(req, res){
var product = new Product(makeProduct(req.body, req.files));
console.log(product);
product.save();
return res.render('admin/index');
};
var makeProduct = function(product, photos){
console.log(photos);
product.quantities = product.quantities.split(',');
product.description = _.map(product.description, function(val, index){
return {
item: val,
quantity: product.quantities[index]
};
});
console.log(product.description);
delete product.quantities;
product.photos = [];
product.photos.push(photos.foto1[0].location);
product.photos.push(photos.foto2[0].location);
return product;
};
另外,对于依赖项:
"dependencies": {
"async": "1.3.0",
"aws-sdk": "^2.4.2",
"body-parser": "1.13.2",
"chai": "^3.4.1",
"compression": "1.5.1",
"connect-flash": "0.1.1",
"connect-mongo": "0.8.1",
"cookie-parser": "1.3.5",
"cookie-session": "1.2.0",
"csurf": "1.9.0",
"dotenv": "^2.0.0",
"easyimage": "^2.1.0",
"express": "4.13.1",
"express-session": "1.11.3",
"forever": "0.14.2",
"jade": "^1.11.0",
"method-override": "2.3.3",
"mongoose": "4.0.6",
"mongoose-user": "latest",
"morgan": "1.6.1",
"multer": "^1.1.0",
"multer-s3": "^2.3.2",
"passport": "0.2.2",
"passport-local": "1.0.0",
"request": "^2.69.0",
"sha1": "^1.1.1",
"underscore": "^1.8.3",
"view-helpers": "0.1.5",
"winston": "1.0.1",
"xml2json": "^0.9.1"
}
我认为原因是multer,但后来我更改了multer版本并停止使用它作为全局中间件,我仍然收到此错误。
注意:如果我将操作更改为在我的网址后面包含“?_csrf =#{csrfToken}”,它会有效,但我想要一个更清晰的解决方案,如果有的话。
答案 0 :(得分:1)
制作这样的表格
<form method="post" action="/?_csrf=<%=csrfToken%>"
并删除此
input(type="hidden" name="_csrf" value= csrf_token)
答案 1 :(得分:0)
form(action="/adminfruta/criarproduto/?_csrf=<%=csrfToken%>" enctype="multipart/form-data" method="post")
并且您的表格也必须污染
input(type="hidden" name="_csrf" value= csrf_token)