在 Sails.js 中更新用户模型时更改密码

Posted

技术标签:

【中文标题】在 Sails.js 中更新用户模型时更改密码【英文标题】:Password gets changed when updating User Model in Sails.js 【发布时间】:2015-04-08 05:13:23 【问题描述】:
/**
* User.js
*
* @description :: TODO: You might write a short summary of how this model works and what it represents here.
* @docs        :: http://sailsjs.org/#!documentation/models
*/

var bcryptjs = require('bcryptjs');

function hashPassword(values, next) 
bcryptjs.hash(values.password, 10, function(err, hash) 
    if (err) 
        return next(err);
    
    values.password = hash;
    next();
);


module.exports = 

connection: 'mysql',

attributes: 
        id:
        primaryKey: true,
        autoIncrement: true,
        unique: true
        ,
        displayname:
        type: 'STRING',
        required: true
        ,
        password:
        type: 'STRING',
        required: true
        ,

    // Override toJSON instance method to remove password value
    toJSON: function() 
        var obj = this.toObject();
        delete obj.password;
        return obj;
    ,

,
// Lifecycle Callbacks
beforeCreate: function(values, next) 
    hashPassword(values, next);
,


beforeUpdate: function(values, next) 
    if (values.password) 
        hashPassword(values, next);
    
    else 
        //IMPORTANT: The following is only needed when a BLANK password param gets submitted through a form. Otherwise, a next() call is enough.
        User.findOne(values.id).done(function(err, user) 
            if (err) 
                next(err);
            
            else 
                values.password = user.password;
                next();
            
        );
    
,


validPassword: function(password, user, cb) 
bcryptjs.compare(password, user.password, function(err, match) 
  if (err) cb(err);

  if (match) 
    cb(null, true);
   else 
    cb(err);
  
);


;

hashPassword(values, next);在 beforeUpdate 方法中更改密码,同时更改用户模型的任何值,尽管我没有在“参数”中发送密码值。但是当我为用户更改密码时它工作正常。

示例:当我更改当前用户的密码时,它应该更改密码、散列并存储在数据库中。但是当我更新用户模型中的其他数据时,我不希望密码被更改(更改为随机密码)。

编辑:现在工作,更正代码: 现在,只有在 Update 方法中发送 password:password 时,它才会更新密码(散列和存储),否则它只会更新提供的用户字段。

控制器(UserController.js):

updateDisplayName: function(req, res) 

var userid = req.token;
var newDisplayName = req.param('newdisplayname');

User.update(id: userid,displayname: newDisplayName).exec(function afterwards(err,updated)

if (err) 
res.json(err);
 else 
res.json("Success");

);

,

模型(User.js):

beforeUpdate: function(values, next) 
if(values.password) 
hashPassword(values, next);
 else 
next();

,

【问题讨论】:

只检查 hashPassword 方法是否在 beforeUpdate 函数中被调用 这是问题,但仍在尝试找出解决方法。 只需在 beforeUpdate 函数中为 value.password 输入一条控制台消息,然后检查 value.password 的值是什么 我尝试了console.log,似乎旧的哈希密码再次被哈希并存储在数据库中。使旧密码不再起作用。 【参考方案1】:

据我所知,问题在于即使您没有更改密码参数,您也会通过它。当它到达时对其进行 bcrypt.compare 怎么样。如果匹配,则不要重新散列密码。如果它不匹配它被认为是一个新密码,你继续一个哈希它?

我自己也有这个难题,我打算采用这种方法。

【讨论】:

【参考方案2】:
beforeUpdate: function(values, next) 
if (values.password) 
    hashPassword(values, next);

此代码存在每次更新用户模型(不是更改密码)时的问题,例如:更新显示名称。用户模型中的密码已经加密,再次加密后旧密码将失效。

解决方案是在正常更新之前从用户模型中删除密码属性(不更改密码)。在更改密码期间,必须将新密码设置为 user.password 并调用 update。

【讨论】:

更新时我没有传递任何密码属性,我尝试了 if (values.password !== null),但仍然被更改。

以上是关于在 Sails.js 中更新用户模型时更改密码的主要内容,如果未能解决你的问题,请参考以下文章

在 Sails Js App 中将用户模型密码发送到客户端

我可以根据每个请求更改数据库吗(Sails.js)

从 Sails.js 中的关联模型访问模型的属性

如何在sails.js 模型中添加具有整数数据类型数组的属性?

Sails.js + Waterline:通过关联进行多对多

svn服务器用户名密码更改后,如何更新本地用户名密码