据我所知,在Web开发中,应在客户端和服务器端验证用户输入。
我很难确定在服务器端验证输入的位置 例如,在请求通过中间件并到达控制器之后。在控制器中,我有其他模块将接受输入并最终到达目的地然后响应。
输入的验证是否应完全在控制器中完成,以便当输入输入其他模块时,它是否符合预期?或者我应该检查输入模块中的输入?或者我应该做一个"浅"检查控制器中的输入(基本原始类型检查等)并保留模块本身的业务逻辑检查(值是正数?,负数?等)?
示例代码:
controller.js
var mashUp = require('./mashupService');
var create = function(req, res) {
var user = req.body.user;
var imageName = req.body.imageName;
var description = req.body.description;
//more validation here?
if (!user) {
return ApiResponse(req, res, new Error('no user'));
} else if (!imageName) {
return ApiResponse(req, res, new Error('no image name'));
} else if (!description) {
return ApiResponse(req, res, new Error('no description'));
}
// continue with business
mashUp(user, imageName, description, function(err, id) {
if (err) {
return ApiResponse(req, res, new Error('mashup error'));
}
return ApiResponse(req, res, { id: id });
});
};
`其他模块,库等等'
var User = require('./model/user');
function mashUp(user, imageName, desc, callback) {
//more validation here?
User.find({ user: user }, function(err, _user) {
//do stuff
callback(err, id) ;
});
}
module.exports = mashUp
答案 0 :(得分:1)
从不同角度验证数据时,存在一些差异:
模型验证: 当你有一个需要应用于你的数据模型的规则时,如需要,min,max,match等,如果任何验证在大多数情况下都会失败,那么这些规则是用任何orm或odm构建的你可以从那里处理。
如果您需要实现更复杂的逻辑,您可以选择设置自定义验证器。
这是一个moongose的例子:
var UserSchema = new Schema({
firstName: {
type: String,
trim: true,
default: '',
validate: [customValidator, 'Please fill in your first name']
// custom validator
},
lastName: {
type: String,
trim: true,
default: '',
validate: [customValidator, 'Please fill in your last name']
// custom validator
},
displayName: {
type: String,
trim: true
},
email: {
type: String,
trim: true,
unique: true,
default: '',
validate: [customValidator, 'Please fill in your email'],
// custom validator
match: [/.+\@.+\..+/, 'Please fill a valid email address']
//match validator
},
username: {
type: String,
unique: true,
required: 'Please fill in a username', //required validator
trim: true
}
});
有关进一步参考,请查看mongoose验证
商业规则
这更适用于您当前正在描述的方案,处理可能适用于系统中特定环境或用户历史记录的规则。
我不建议管理控制器中的验证,竖起大拇指的规则是创建Fat模型和瘦调控制器,你可以google它但随机我选择了这个presentation和article
据说我更喜欢在控制器执行之前在中间件中进行这些验证。
让以下案例
编辑文章时,请验证该ID是否属于该用户 正在请求编辑
exports.validateArticle = function(req, res, next){
var userId = req.param('userId'),
articleId = req.param('articleId');
// TODO: logic validation
}
然后在控制器执行之前连接中间件,如
app.route('/article').all( rule.validateArticle ).post(controller.editArticle);
通过这种方式,您不会通过一堆验证来污染您的控制器,您也可以将验证从一个控制器重用到另一个控制器。
作为客户端侧面注释验证是为了用户体验,但不依赖它们作为系统的正确验证器。
这里只有我的两分钱, 我希望有所帮助。
喝彩!
答案 1 :(得分:0)
这是关于数据验证的。 由于客户端数据通常不可靠,因此无需在客户端进行数据验证。必须在服务器上验证正确的数据。我建议你在控制器而不是其他模块中进行验证。让我们来看看你的例子:
var create = function(req, res) {
var user = req.body.user;
var imageName = req.body.imageName;
var description = req.body.description;
//more validation here?
答案:是的。想想用户是否存在或有 许可,描述至少有10个字符,包含非法字符等。
if (!user) {
return ApiResponse(req, res, new Error('no user'));
} else if (!imageName) {
return ApiResponse(req, res, new Error('no image name'));
} else if (!description) {
return ApiResponse(req, res, new Error('no description'));
}
//Btw, here is kind of validation right?
//but it looks like that you only want to check if user is posted,
//then imageName and description will be ignored.
//There may be some logic error here.
最后,我还建议您创建一个专门用于数据验证的模块。