我正在使用NodeJS,bcrypt-nodejs(https://github.com/shaneGirish/bcrypt-nodejs)和Bluebird用于承诺。提出这个代码,并想知道是否有更好的方法来做同样的事情。我有模块:
var Promise = require("bluebird"),
bcrypt = Promise.promisifyAll(require('bcrypt-nodejs'));
// ....[some othe code here]
Users.prototype.setPassword = function(user) {
return bcrypt.genSaltAsync(10).then(function(result) {
return bcrypt.hashAsync(user.password, result);
});
};
然后从另一个模块调用users.setPassword
,如下所示:
app.post('/api/v1/users/set-password', function(req, res, next) {
users.setPassword(req.body).then(function(result) {
// Store hash in your password DB.
console.log(result[1]);
res.json({
success: true
})
})
.catch(function(err) {
console.log(err);
});
});
它始终以“[错误:没有给出回调函数。]”消息结束,因为bcrypt.hashAsync
似乎需要4个参数。原始的,未经过宣传的hash
方法只需要3。当我向hashAsync
添加空回调时,它可以正常工作:
Users.prototype.setPassword = function(user) {
return bcrypt.genSaltAsync(10).then(function(result) {
return bcrypt.hashAsync(user.password, result,function() {});
});
};
有没有更好的方法来做到这一点,而不提供如上所述的空回调?
编辑:
回应Bergi的评论..函数最终将设置密码,我发布问题时没有那么远。现在到目前为止,如果事情不太正确,请告诉我:
Users.prototype.setPassword = function(user) {
return bcrypt.genSaltAsync(10).then(function(result) {
return bcrypt.hashAsync(user.password, result, null);
})
.then(function(result) {
// store in database
console.log("stored in database!");
return result;
});
};
答案 0 :(得分:9)
bcrypt.hashAsync似乎需要4个参数。原始的,非promisified哈希方法只需要3。
反之亦然。来自the docs:
hash(data, salt, progress, cb)
data
- [必需] - 要加密的数据。salt
- [必需] - 用于散列密码的salt。progress
- 在哈希计算过程中调用以表示进度的回调callback
- [REQUIRED] - 数据加密后将被触发的回调。
原始方法有4个参数,hashAsync
将取3并返回一个承诺。
然而,在您的代码中,您只传递了两个。您不需要传递空函数,参数不是 [REQUIRED] 意味着您可以传递null
(或任何其他虚假值)。 bcrypt will create such an empty function itself。所以使用
function (data) {
return bcrypt.genSaltAsync(10).then(function(result) {
return bcrypt.hashAsync(data.password, result, null);
});
}
答案 1 :(得分:0)
这是我在一段时间内做过的项目中我的承诺的bcrypt。蓝鸟对于这么小的简单库来说并不是必需的。
app.post('/signup', function(req, res) {
var username = req.body.username;
var password = req.body.password;
var user = handler.userExists(username)
.then(function(answer){
if (answer !== null){
console.log(req.body.username + " was taken")
res.send({login: false, message: req.body.username + " is taken"});
return null;
} else if (answer === null) {
console.log("username not taken")
return handler.makeUser(username, password);
}
})
.catch(function(err){
console.log("error during user lookup:", err);
res.status(404).send({message:"database error:", error:err});
})
if (user !== null){
user
.then(function(x){
console.log("this is returned from handler.makeUser: ", x)
console.log(x.ops[0]._id)
req.session.user = x.ops[0]._id;
var mindSeal = {
userSettings: {
username: x.ops[0]._id,
newCardLimit: null,
tValDefault: 128000000,
lastEdit: req.body.time,
todayCounter: 0,
allTimeCounter: 0,
cScaleDefault: {0: 0.9, 1: 1.2, 2: 1.8, 3: 2.5},
accountMade: req.body.time
},
decks: {}
};
handler.setMindSeal(req.session.user, mindSeal, req.body.time);
res.send({
login: true,
mindSeal: mindSeal
});
})
.catch(function(error){
console.log("make user error: " + error);
res.status(401).send({message:"failed.",error:error,login:false});
})
}
});
app.post('/login', function(req, res) {
var username = req.body.username;
var password = req.body.password;
handler.login(username, password)
.then(function(obj){
if (obj.bool){
console.log("username and password are valid. login granted.");
req.session.user = obj.user;
console.log("obj is:", obj)
var mindSeal = {decks:obj.mindSeal.decks, userSettings:obj.mindSeal.userSettings};
console.log("mindSeal sending:", mindSeal);
res.status(200).send({
login: true,
message:"Login Successful",
mindSeal: obj.mindSeal
});
}
else {
console.log("password invalid")
res.status(401).send({login: false, message:"Your username and/or password are incorrect."})
}
})
.catch(function(error){
console.log(error);
res.status(404).send({message:"database error:", error:err});
})
});
示例用法:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/my_image"/>
</LinearLayout>
仅限概念性示例;借用并略微修改了我的一些旧代码。工作代码(我看到我现在想改进的东西,但它确实有用),这里:https://github.com/finetype/mindseal/blob/master/server.js
答案 2 :(得分:-5)
也许你可以使用another bcrypt library,使用更好的API来消除对promises的需求。
Users.prototype.setPassword = function(user) {
return TwinBcrypt.hashSync(user.password, 10);
};
或者,进度跟踪:
Users.prototype.setPassword = function(user) {
function progress(p) {
console.log( Math.floor(p*100) + '%' );
}
TwinBcrypt.hash(user.password, 10, progress, function(result) {
// store in database
console.log("stored in database!");
return result;
});
};