在服务器端验证用户输入的位置?

时间:2014-10-17 14:17:53

标签: javascript node.js validation

据我所知,在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

2 个答案:

答案 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它但随机我选择了这个presentationarticle

据说我更喜欢在控制器执行之前在中间件中进行这些验证。

让以下案例

  

编辑文章时,请验证该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.

最后,我还建议您创建一个专门用于数据验证的模块。