当前位置: 首页 > 知识库问答 >
问题:

使用enctype=“多部分/表单数据”时,我收到CSRF错误

田念
2023-03-14

每当我将enctype="multipart/form-data"添加到我的html表单时,我都会得到ForBiddenError:无效的csrf令牌

如果我把enctype去掉它就会工作

我这样发送csrf代码:输入(type="隐藏"name="_csrf"value=csrf_token)

我的Express文件:

var express = require('express');
var session = require('express-session');
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) {

  // Static files middleware

  // 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' }));

  // 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:
        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
                .choose Escolha foto 1 (tamanho 250x250 px):
                input(type="file" name="foto1")
            .half
                .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 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);
}

最后是管理员。js文件

exports.createProduct = function(req, res){
  var product = new Product(makeProduct(req.body, req.files));
  product.save();
  return res.render('admin/index');
};

var makeProduct = function(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",
"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",
"easyimage": "^2.1.0",
"express": "4.13.1",
"express-session": "1.11.3",
"jade": "^1.11.0",
"method-override": "2.3.3",
"morgan": "1.6.1",
"multer": "^1.1.0",
"multer-s3": "^2.3.2",
"passport": "0.2.2",
"passport-local": "1.0.0",
"sha1": "^1.1.1",
"underscore": "^1.8.3",
"view-helpers": "0.1.5",
}

我认为原因是multer,但后来我更改了multer版本并停止将其用作全局中间件,我仍然会遇到这个错误。

注意:如果我将操作更改为在URL后面包含“?\u csrf={csrfToken}”,那么它会起作用,但我想要一个更干净的解决方案,如果有的话。

共有2个答案

季稳
2023-03-14

<代码>表单(action="/adminfruta/criarproduto/?_csrf=

你的表格也必须包含这个

输入(type=“hidden”name=“\u csrf”value=csrf\u token)

都超英
2023-03-14

制作这样的表单

<form method="post" action="/?_csrf=<%=csrfToken%>"

并删除此

input(type="hidden" name="_csrf" value= csrf_token)
 类似资料:
  • 我在jsp文件中有此表单: 这个广告表单类: 在相应的控制器中,我使用此参数接收数据: 问题是当csrf在sping-security.xml被禁用它的工作正常-我可以看到选择的文件在广告orm.get图像(),但当我启用csrf它停止工作: 我试图通过以下步骤解决这个问题: > 我定义了filterMultipartResolver:

  • 我一直在使用Spring Security 3.2.0中的新csrf功能。并注意到它似乎不适用于enctype=“多部分/表单数据”表单。 我有一个简单的Spring形状: 隐藏的csrf输入按预期呈现: 但是请求没有通过csrf检查(如果我删除enctype="multipart/form-data",它会很好地工作)。我发现的唯一方法是附加“?_csrf=...”到我的操作url,这是丑陋的,

  • 我正在用spring mvc中的put方法发送一些包含多部分数据的数据。sme进程正在处理post请求,但在put请求中生成错误。这是我的代码片段: 生成的错误是:HTTP状态400-所需的字符串参数“name”不存在 键入状态报告 消息所需的字符串参数“name”不存在 说明客户端发送的请求在语法上不正确。

  • 我正在尝试从接收包含3个参数的多部分请求: 一个 一个 我在控制器中接收到和fine,但json的所有字段都为NULL。会有什么问题吗? JSON 控制器 邮差

  • 如何使用ajax或XMLHttpRequest从javascript调用RESTAPI,以使用内容类型:multipart/form data上载文件。 文件内容是二进制格式的,但我调用的API具有以下请求格式:Authorization:Bearer 我使用以下代码段上传文件内容: 其中formData是二进制格式的文件内容。请建议这是正确的方法还是应该以不同的方式处理。我使用的文件类型是IFC

  • 嗨,我有一个问题,当我可以尝试上载一个文件的属性和元数据到alFresco 5.2使用php 5.4.3,这是我的代码: $pam['body']是这样的: 这显示此错误: 但这个错误意味着一个或多个参数是错误的,但我不知道是哪个,因为服务器有大量的磁盘空间。 有什么帮助吗?有人使用ApiRest Alfresco 5.2和PHP吗?