首页 > 解决方案 > 如何使用 ExpressJS 和 multer 添加 JWT 和字段验证

问题描述

我有一个需要 multipart/form-data 的表单,因为该表单中有一个文件字段。

我正在使用 ExpressJS,我使用 multer 来处理 multipart/formdata。

现在我还需要验证标头中的字段和 JWT。

在我的应用程序中,我使用中间件作为应用程序/JSON 类型,并这样做:

app.delete("/ticket/:ticketId", [
    authValidation.validJWTNeeded,
    authValidation.verifyIfNotLoggedOut,
    authPermission.hasPermissionOrIsSameUser(staffRole),
    ticketController.deleteById
]);

在每个中间件中,我传递参数(req、res、next)并在需要时返回 next,我工作正常。

如果没有先发送文件,我无法用 multer 做到这一点。在文档中,他们会做这样的事情,这不是我想要的,因为文件已经发送:

app.post("/route",
    multer.upload.single("avatar"),
    function (req, res, next) {
    // req.file is the `avatar` file
    // req.body will hold the text fields, if there were any
    })
)

我尝试做这样的事情,但没有奏效:

app.post("/ticket", [
    async (req, res, next) => {
    multer.upload.none();
    let jwt = //req.headers....... this is the jwt sent
    //req.body should have all the fields
    return next
    },
    authValidation.validJWTNeeded,               //Here i verify the JWT for auth
    authValidation.verifyIfNotLoggedOut,         //About the same here
    ticketController.verifyFields,               // /!\ I need to verify if fields are correct
    //function/middleware to upload using multer.upload.single("field"), 
    ticketController.insert                      // If everything above passed, then create the ticket and upload the file
]);

所以我的问题是:如何使用 multer 和使用 multipart/formdata 加密发送的数据进行所有验证?

谢谢!

标签: node.jsexpressmulter

解决方案


所以我想了一个办法,这是一种非常肮脏的方式,恕我直言,但它可以工作......我使用了 multer 的 fileFilter 并在其中添加了所有需要的验证,包括 JWT 验证、字段验证等。通过这样做,如果有人有更适合的方法,请随时回答。

//verify the jwt here

function isLoggedIn(req) {
    if (req.headers['authorization']) {
        try {
            let authorization = req.headers['authorization'].split(' ');
            if (authorization[0] !== 'Bearer') {
                return false
            } else {
                if(jwt.verify(authorization[1], config.jwt_secret)){
                    return true
                }
            }
        } catch (err) {
            return false
        }
    } else {
        return false
    }
}


//verify fields here
function verifField (req) {
    console.log(req.body.title)
    let fieldList = {
        title : false,
        message : false,
        category : false,
        response : false
    };

    if(req.body.title && req.body.title.trim() !== ""){
        fieldList.title = true;
    }

    if(req.body.message && req.body.message.trim() !== ""){
        fieldList.message = true;
    }

    if(req.body.category && ticketModel.ticketModel.schema.path("category").enumValues.includes(req.body.category)){
        fieldList.category = true;
    }

    if(!req.body.response){
        fieldList.response = true;
    }

    return fieldList.title &&  fieldList.message && fieldList.category && fieldList.response
}

//mix them both here + verify type    
function isValid (req) {
    return isLoggedIn(req) && verifField(req) && file.mimetype.match(/jpe|jpeg|png|gif$i/)
}

//export everything here
module.exports = {
    upload : multer({
        storage : storage,
        fileFilter : (req, file, cb) => {
            cb(null, isValid(req))
        }
    })
} ;

推荐阅读