Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

使用express-validator对你的Express应用的用户数据进行验证 #21

Open
huruji opened this issue Feb 19, 2018 · 1 comment
Open

Comments

@huruji
Copy link
Owner

huruji commented Feb 19, 2018

开发web应用时,我们总是需要对用户的数据进行验证,这包括客户端的验证以及服务端的验证,仅仅依靠客户端的验证是不可靠的,毕竟我们不能把所有的用户都当成是普通用户,绕过客户端的验证对于部分用户来说并不是什么难事,因此所有数据应该在服务端也进行一次验证。Express应用可以通过express-validator进行数据验证,这样就不必自己烦琐的为每一个数据单独写验证程序(过来人告诉你这感觉简直糟透了)。

通过一个简单的例子让我们来看看express-validator的便捷,让用户上传一些数据,表单如下:

最简单的服务端代码如下:

var express = require('express');
var bodyParser = require('body-parser');
var expressValidator = require('express-validator');
var check = require('express-validator/check').check;
var validationResult = require('express-validator/check').validationResult;
var app = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));

app.get('/', function(req, res) {
   res.sendFile('index.html', {root:'./test'});
});

app.post('/data', [
    check('email')
        .isEmail()
        .withMessage('must be an email'),
    check('username')
        .isLength({min:6})
        .withMessage('ust be at least 6 chars long')
],function(req, res) {
    var errors = validationResult(req);
    if(!errors.isEmpty()) {
        return res.json({errors: errors.mapped()});
    }
    res.json({msg:'success'});
});

app.listen(4000);

当用户上传数据之后会在服务端对用户的用户名和邮箱进行验证,当数据不符合时,错误信息显示如下:
image.png

从上面的例子中可以看到对数据的验证错误可以随时获取,从而进行处理。
validationResult方法获取捕获的错误,mapped()方法获取具体的错误信息。

express-validator是基于validator.js的,express-validator也类似将API分为check和filter两个部分(关于validator.js的使用可以参考使用validator.js对字符串数据进行验证

check部分

check(field[, message])

field是一个字符串或者是一个数组,message是验证不通过的错误信息,返回验证链(链式调用)

check方法默认会验证req.body、req.cookies、req.headers、req.params、req.query中的字段,如果有相同字段,其中一个不通过就会显示错误信息。

如将以上例子的post地址新增一个名为email的query则错误信息如下:

注意location的值。

如果需要单独验证req.body、req.cookies、req.headers、req.params、req.query的其中一个目标的字段,则可以使用对应的方法bodycookieheaderparamquerybody

oneOf(validationChains[, message])

validationChains是验证链组成的数组,如果验证链至少有一条通过则不显示错误。

var express = require('express');
var bodyParser = require('body-parser');
var expressValidator = require('express-validator');
var check = require('express-validator/check').check;
var oneOf = require('express-validator/check').oneOf;
var validationResult = require('express-validator/check').validationResult;
var app = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));

app.get('/', function(req, res) {
   res.sendFile('index.html', {root:'./test'});
});

app.post('/data', oneOf([
    check('email')
        .isEmail()
        .withMessage('must be an email'),
    check('username')
        .isLength({min:6})
        .withMessage('ust be at least 6 chars long')
]),function(req, res) {
    var errors = validationResult(req);
    if(!errors.isEmpty()) {
        return res.json({errors: errors.mapped()});
    }
    res.json({msg:'success'});
});

app.listen(4000);

validationResult(req)

获取验证的结果是否通过

buildCheckFunction(locations)

从指定的locaation中构建check,locations是body、cookies、headers、params、query一个或者几个组成的数组,相当于指定位置的字段进行验证(请不要忘记check方法会对这5个部分都进行验证)

var buildCheckFunction = require('express-validator/check').buildCheckFunction;
var checkBodyAndQuery = buildCheckFunction(['body','query']);

filter部分

matchedData(req[, options])

获取check的字段数据,也就是获取上文例子出现的错误信息中的value字段值,options为一个json对象,允许的字段为

{
    onlyValidData:true,
    locations:[]
}

onlyValidData显然就是是否仅仅获取验证的字段值,默认为true,locations就是指定位置。

app.post('/data', [
    check('email')
        .isEmail()
        .withMessage('must be an email'),
    check('username')
        .isLength({min:6})
        .withMessage('ust be at least 6 chars long')
],function(req, res) {
    var queryData = matchedData(req, {locations: ['query']});
    var bodyData = matchedData(req, {locations: ['body']});
    console.log(queryData);
    console.log(bodyData);
    var errors = validationResult(req);
    if(!errors.isEmpty()) {
        return res.json({errors: errors.mapped()});
    }
    res.json({msg:'success'});
});

sanitize(fields)

类似于check,只不过是返回一个处理链,理所当然有类似的sanitizeBodysanitizeCookiesanitizeParamsanitizeQuerybuildSanitizeFunction。(注意req.headers在这里不适用)

customSanitizer(sanitizer)

进行自定义处理程序

除此之外,express-validator保留了版本3的作为express中间件的使用方式。

var express = require('express');
var expressValidator = require('express-validator');

app.use(expressValidator({
    errorFormatter: function(param, message, value) {
        return {
            param: param,
            message: message,
            value: value
        }
    },
    customValidators: {
        isEmail: function(value) {
            return /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value);
        },
        isString: function(value) {
            return typeof value === 'string';
        },
        isObject: function(value) {
            return (typeof value === 'object' && !Array.isArray(value));
        },
        isArray: function(value){
            return Array.isArray(value);
        },
        isBoolean: function(value) {
            return value === true || value === false;
        },
        custom: function(value, callback) {
            if(typeof value !== 'undefined') {
                callback(value);
                return true;
            } else {
                return false;
            }
        }
    }
}));

可以在使用use加载中间件的时候自定义第三方验证方法和处理方法。

验证数据时的使用方式如下:

req.checkBody('email', '邮件格式不正确').isEmail();
req.checkBody('password', '密码不能小于6位').isLength(6);
@d1y
Copy link

d1y commented Nov 18, 2019

感谢老哥, 学习了~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants