【问题标题】:Multer and CSRF and <form action="?_method=PUT">Multer 和 CSRF 以及 <form action="?_method=PUT">
【发布时间】:2019-07-11 02:06:42
【问题描述】:

所以,我刚刚在我的项目中添加了 multer 和 cloudinary。 每当我使用我的表单向我的数据库添加一些东西时。它给出了这个错误 "ForbiddenError: 无效的 csrf 令牌"

但我已通过在表单中​​的操作属性中添加 ?_csrf=&lt;%= csrfToken %&gt;" 来解决此问题

<form action="/admin?_csrf=<%= csrfToken %>" method="POST" enctype="multipart/form-data">

现在,我正在尝试为我的更新路线做同样的事情。 它给了我与“ForbiddenError: invalid csrf token”之前相同的错误

我试过做 &lt;form action="/admin/&lt;%= prod._id %&gt;?_method=PUT?_csrf=&lt;%= csrfToken %&gt;" method="POST" enctype="multipart/form-data"&gt;

或者这个

&lt;form action="/admin/&lt;%= prod._id %&gt;?_method=PUT?_csrf=&lt;%= csrfToken %&gt;" method="POST" enctype="multipart/form-data"&gt;

或者这个

&lt;form action="/admin/&lt;%= prod._id %&gt;?_method=PUT_csrf=&lt;%= csrfToken %&gt;" method="POST" enctype="multipart/form-data"&gt;

或者这个

&lt;form action="/admin/&lt;%= prod._id %&gt;?_csrf=&lt;%= csrfToken %&gt;_method=PUT" method="POST" enctype="multipart/form-data"&gt;

你知道......不同种类的变化......希望一个会起作用。哈哈

无论如何,我正在做的事情是不可能的吗?我的 action 属性中可以有 2 种方法?

我还有其他方法可以做到这一点吗?

Edit.ejs

<section class="no-padding-top">
  <div class="container-fuid">
    <div class="row">
      <div class="col-lg-12">
        <div class="block">
        <div class="title"><strong>Edit Item</strong></div>
          <form action="/admin/<%= prod._id %>?_method=PUT" method="POST" enctype="multipart/form-data">
           <div class="form-group row">
              <label class="col-sm-3 form-control-label">Product Name</label>
              <div class="col-sm-9">
              <input type="text" class="form-control" name="prod[name]" value="<%= prod.name %>" required>
              </div>
            </div>
            <div class="form-group row">
              <label for="image" class="col-sm-3 form-control-label">Product Image</label>
              <div class="col-sm-9">
              <input type="file" id="image" name="image" accept="image/*" >
              </div>
            </div>
            <div class="form-group row">
              <label class="col-sm-3 form-control-label">Product Price</label>
              <div class="col-sm-3">
              <input type="text" class="form-control" name="prod[price]" value="<%= prod.price %>" required>
              </div>
              <label class="col-sm-1 form-control-label">Product Quantity</label>
              <div class="col-sm-2">
              <input type="text" class="form-control" name="prod[quantity]" value="<%= prod.quantity %>" required>
              </div>
            </div>
            <div class="form-group row">
              <label class="col-sm-3 form-control-label">Product Brand</label>
              <div class="col-sm-3">
              <input type="text" class="form-control" name="prod[brand]" value="<%= prod.brand %>"  required>
              </div>
              <label class="col-sm-1 form-control-label">Product type</label>
              <div class="col-sm-2">
              <input type="text" class="form-control" name="prod[type]" placeholder="Types of produces. i.e Wheels, Lights, Steering Wheels..." value="<%= prod.type %>" required>
              </div>
            </div>
            <div class="form-group row">
              <label class="col-sm-3 form-control-label">Product Description</label>
              <div class="col-sm-9">
              <textarea cols="30" rows="10" class="form-control" name="prod[description]" required> <%= prod.description%> </textarea>
              </div>
            </div>
            <div class="form-group row">
              <div class="col-sm-9 ml-auto">
                <button type="submit" class="btn btn-primary">Edit Item</button>
                <a href="/admin" class="btn btn-info ml-3">Cancel</a>
              </div>
            </div>
            <input type="hidden" name="_csrf" value="<%= csrfToken %>">
          </form>
        </div>
      </div>
    </div>
  </div>
</section>

多云开始

var multer = require('multer');
var storage = multer.diskStorage({
  filename: function(req, file, callback) {
    callback(null, Date.now() + file.originalname);
  }
});
var imageFilter = function (req, file, cb) {
    // accept image files only
    if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/i)) {
        return cb(new Error('Only image files are allowed!'), false);
    }
    cb(null, true);
};
var upload = multer({ storage: storage, fileFilter: imageFilter})

var cloudinary = require('cloudinary');
cloudinary.config({ 
  cloud_name: 'pitscaraccessories', 
  api_key: process.env.CLOUDINARY_API_KEY, 
  api_secret: process.env.CLOUDINARY_API_SECRET
});

更新路线

router.put("/:id", middleware.isLoggedIn, middleware.isAdmin, upload.single('image'), function(req, res) {
    Product.findById(req.params.id, async function(err, prod) {
        if (err) {
            req.flash("error", err.message);
        } else {
            if (req.file) {
                try {

                    await cloudinary.v2.uploader.destroy(prod.imageId);
                    var result = await cloudinary.v2.uploader.upload(req.file.path);
                    prod.image = result.secure_url;
                    prod.imageId = result.public_id;

                } catch (err) {
                    req.flash("error", err.message);
                    return res.redirect("back");
                }
            }

            prod.save();

            req.flash("success", "Updated Successfully");
            res.redirect("/admin");
        }
    });
});

【问题讨论】:

    标签: node.js express csrf multer cloudinary


    【解决方案1】:

    通过对我的代码执行此操作来解决此问题。将我的路线从.put 更改为.post

    并手动更新内部的每个输入。

    router.post("/:id", middleware.isLoggedIn, middleware.isAdmin, upload.single('image'), function(req, res) {
        Product.findById(req.params.id, async function(err, prod) {
            if (err) {
                req.flash("error", err.message);
            } else {
                if (req.file) {
                    try {
                        await cloudinary.v2.uploader.destroy(prod.imageId);
                        var result = await cloudinary.v2.uploader.upload(req.file.path);
                        prod.image = result.secure_url;
                        prod.imageId = result.public_id;
                    } catch (err) {
                        req.flash("error", err.message);
                        return res.redirect("back");
                    }
                }
    
                prod.name = req.body.name;
                prod.price = req.body.price;
                prod.quantity = req.body.quantity;
                prod.brand = req.body.brand;
                prod.type = req.body.type;
                prod.description = req.body.description;
    
                prod.save();
    
                req.flash("success", "Updated Successfully");
                res.redirect("/admin");
            }
        });
    });
    
    

    并对我的表单元素执行此操作

    &lt;form action="/admin/&lt;%= prod._id %&gt;?_csrf=&lt;%= csrfToken %&gt;" method="POST" enctype="multipart/form-data"&gt;

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题,也许你没有尝试足够的排列;D

      这个语法对我有用

      <form action="/users/<%= user._id %>?_method=PUT&_csrf=<%= csrfToken %>" method="POST" enctype="multipart/form-data">
      

      【讨论】:

        猜你喜欢
        • 2020-05-19
        • 2019-11-29
        • 2012-01-13
        • 2017-07-29
        • 1970-01-01
        • 2015-05-14
        • 1970-01-01
        • 1970-01-01
        • 2019-07-05
        相关资源
        最近更新 更多