mongoose如何防止用户已经使用用户名修改用户名

时间:2015-07-17 12:50:28

标签: node.js mongodb express mongoose

我有一个身份验证系统,用户可signup username / passwordfacebook signin provider / providerId

我想阻止更改用户名,但如果他们使用facebook,我允许他们设置username一次。是否可以在user模型中实现它?

这是我目前的实施。

//username check unique
UserSchema.pre('save', true, function(next, done) {
    var self = this //in case inside a callback



    //sns provider, OK not to have username
    if (self.provider && self.provider !== 'local' && !self.username) {
        done()
        return next()
    }
    //not modified
    if (! self.isModified('username')) {
        done()
        return next()
    }

    mongoose.model('User').findOne({username: self.username}, function(err, user) {
        if (err) {
            done(err)
        } else if (user) {
            //todo: put msg in validation.js
            self.invalidate('username', 'username must be unique')
            done(helper.getValidationError('username must be unique'))
        } else {
            done()
        }
    })

    return next()
})

//username check is valid username
UserSchema.pre('save', true, function(next, done) {
    var self = this

    if (self.provider && self.provider !== 'local' && !self.username) {
        done()
        return next()
    }
    //username is required for local strategy
    var msg = helper.validation.user.username(self.username)
    if (msg) {
        self.invalidate('username', msg)
        done(helper.getValidationError(msg))
    }
    else {
        done()
    }

    return next()
})

帮助程序验证定义为:

exports.user = {
    username: function(input) {
        if (!input)
            return 'username is required' //Note: required only for Local Strategy
        var min = 3
        var max = 10
        if (input.length < min)
            return 'username min of length is ' + min
        if (input.length > max)
            return 'username max of length is ' + max
        return null
    }
}

2 个答案:

答案 0 :(得分:3)

您可以检查原始用户名是否为空。所有验证都在模型中。您不必修改控制器或路由器中的任何内容。

UserSchema.post('init', function() {
    this.original = this.toObject()
})





UserSchema.pre('save', true, function(next, done) {
    var self = this

    if (! self.isModified('username')) {
        done()
        return next()
    }

    //To prevent Facebook user to delete username (and recreate a different one) with !self.original.username
    if (self.provider && self.provider !== 'local' && !self.username && !self.original.username) {
        done()
        return next()
    }

    //prevent change of username
    if (self.original.username) {
        self.invalidate('username', 'cannot modify username')
        done(helper.getValidationError('cannot modify username'))
    }

    mongoose.model('User').findOne({username: self.username}, function(err, user) {
        if (err) {
            done(err)
        } else if (user) {
            self.invalidate('username', 'username must be unique')
            done(helper.getValidationError('username must be unique'))
        } else {
            done()
        }
    })

    return next()
})

答案 1 :(得分:0)

尝试在预保存功能中将username属性设置为null。这应该会阻止用户更新它的用户名。

还可以选择从请求正文中删除用户名:

delete req.body.username;
User.update(query, req.body , options, callback)