Tehila
Tehila

Reputation: 1102

Using multer, CSRF and express-validator together in nodeJs

In my node.js app I have an ejs form which has some text input fields that express-validator should validate, an image file which uses multer, and an hidden input that contains a CSRF token. (I have this token in all the other forms in my app too)

The problem is, that the CSRF middleware is global and runs for each request before the middlewares in my routes files, and the multer middleware runs in one of this routes files.

I know that multer should be placed before the CSRF middleware, but in my case I have to put multer inside the routes - because I want it to run after express-validator finished validating the text inputs.

Why do I want multer to run before express-validator and can't make it global?

Because if I make multer global, then in case I have a valid file in my form, even if the text inputs are invalid - the file will still uploaded by multer, because multer has ran before the express-validator started runnig, and that's the big problem.

So to solve this, I placed the multer middleware inside the routes and after the validator, but now there's the issue with the csrf that needs multer.

Here are parts of my code:

multer middleware:

const fileStorage = multer.diskStorage({
    destination: (req, file, cb) => {
      cb(null, "images");
    },
    filename: (req, file, cb) => {
      cb(null, uuidv4() + "-" + file.originalname);
    },
  });
  
  const fileFilter = (req, file, cb) => {
    if (file.mimetype === "image/jpeg" || file.mimetype === "image/jpg" || file.mimetype === "image/png") {
      cb(null, true);
    } else {
      cb(null, false);
    }
  };

 
module.exports = multer({ dest: "images", storage: fileStorage, fileFilter:fileFilter}).single("image");

The route file that contains multer and express-validator:

const { productValidators } = require('../middleware/validators')//The express validator middlewares
const multer = require('../middleware/multer')

router.post("/add-product",isAuth,productValidators,multer,adminController.postAddProduct);
    
router.post("/edit-product",isAuth, productValidators,multer, adminController.postEditProduct);

So in short, my problem is that I need multer to stop uploading the image if other validation failed. But the only way to do so is by adding multer middleware after the express-validator instead of making it a global middleware, which causes the csrf problem.

Is there an alternative to this?

Thanks for the help.

Upvotes: 1

Views: 314

Answers (1)

Isaac Da Silva Correa
Isaac Da Silva Correa

Reputation: 11

The middleware using express receive methods the function req:Request, res:Response, next: NextFunction.

Primary Validated middleware, if not allowed:

return res.status(401).json({
  message: 'Error identification keys'
})

Upvotes: -1

Related Questions