2015-04-01 198 views
1

我正在使用node.js,bcrypt,sequelize和passport設置登錄,並且我在線查看了文檔,但由於某些原因,.compare函數始終返回false,即使當我知道密碼匹配。bcrypt-nodejs.compare總是返回false

在我的模型我添加了一個beforCreate鉤來加密口令:

beforeUpdate: function(user, options, fn) { 
    encryptPassword(user, options, fn); 
} 

encryptPassword功能:

encryptPassword = function(user, options, fn) { 
    if (!user.changed('password')) 
     return fn(); 

    bcrypt.hash(this.password, null, null, function(err, hash) { 
     if (err) return fn(err); 
     user.password = hash; 
     fn(); 
    }); 
} 

我的控制,我創建用戶:

User 
    .create({ 
     username: req.body.username, 
     password: req.body.password 
    }) 
    .then(function() { 
     res.json({ 
      message: 'New beer drinker added to the locker room!' 
     }); 
    }); 

那效果很好,用戶使用哈希密碼存儲在我的數據庫中。

現在我嘗試登錄用戶使用護照

passport.use(new BasicStrategy(
    function(username, password, callback) { 
     User 
      .find({ 
       where: { 
        username: username 
       } 
      }) 
      .then(function(user) { 
       // No user found with that username 
       if(!user) return callback(null, false); 

       // Make sure the password is correct 
       user.verifyPassword(password, function(err, isMatch) { 
        if(err) return callback(err); 

        // Password did not match 
        if(!isMatch) return callback(null, false); 

        // Success 
        return callback(null, user); 
       }); 
      }) 
      .catch(function(err) { 
       return callback(err); 
      }); 
    } 
)); 

這個過程調用user.verifyPassword這是我的用戶模型的instanceMethod。

verifyPassword: function(password, callback) { 
    bcrypt.compare(password, this.password, callback); 
} 

但是無論密碼是否匹配,回調總是假的。有沒有人有任何想法我做錯了?我試圖切換到bcrypt,但我無法安裝它,因爲node-gyp rebuild總是失敗,抱怨它無法找到我安裝的python的env變量。另外,我不想在屁股上試圖讓服務器開發人員設置一個具有正常bcrypt的所有依賴和東西的服務器。

回答

2

加密密碼時,我使用了未定義的this.password。我需要使用user.password來獲取當前密碼。

bcrypt.hash(user.password, null, null, function(err, hash) { 
    if (err) return fn(err); 
    user.password = hash; 
    fn(); 
}); 
+0

你是一個拯救生命的人我也做過這樣的事情,並認爲Bcrypt是罪魁禍首。謝謝!此外,您應該將此標記爲解決問題的答案。 – Rafael 2015-06-27 16:51:59

0

你實際上沒有將密碼傳遞給verifyPassword函數。

user.verifyPassword(password, function(err, isMatch) { 
    ...    ^^^^^^^^ 
});` 

該密碼變量沒有實際定義。當您處於.then()函數中時,您可以訪問從數據庫返回的對象。無論是單個結果還是結果集。

user.verifyPassword(user.password, function(err, isMatch) { ... }); 
        ^^^^^^^^^^^^^ 

你必須訪問你從.findAll()查詢返回的對象中的數據。

希望這會有所幫助。

+0

密碼變量在passport.use前面定義的幾行......,如果我做了你的建議,並使用由數據庫返回我會比較存儲在對數據庫加密值的值來自數據庫的加密值,它總是返回false。我需要比較輸入登錄的值與我正在做的DB中的加密值。 passport.use(新的BasicStrategy( \t函數(用戶名,密碼,回調){ – efarley 2015-04-02 17:27:54

+0

)哦,我的錯誤,你是正確的比較數據庫與它自己的價值問題是範圍,我認爲。 '前面定義的變量,在你嘗試使用它的'.then()'函數中沒有範圍。 – mikemimik 2015-04-02 17:36:36

+0

我已經證實情況並非如此。我使用郵遞員在該行上插入一個斷點,並確認密碼變量的值是用戶輸入的密碼值。 – efarley 2015-04-02 18:35:58