我目前遇到登录代码问题,它应该使用用户名和密码,在数据库中找到相应的哈希值,比较它们,签署JWT并返回它以便将其发送回用户:
async login(username, password): Promise<boolean | void> {
// TODO: Fix typing.
// Types the return as void currently - should return object.
// No return at all either, however console.log prints result - check SO when you have time
const dbPwdHash = await this.userRepository.createQueryBuilder('user')
.select(['user.password', 'user.id'])
.where('user.username = :username', {username})
.getOne();
return compare(password, dbPwdHash.password)
.then(
(res) => {
if (res) {
return sign({ id: dbPwdHash.id }, this.privateKey, { algorithm: 'ES512' }, (err, token) => {
if (err) {
return {err};
} else {
console.log(token);
return {data: token};
}
});
}
},
)
.catch(
(err) => {
console.log(err);
},
);
}
类型定义类型为compare和sign的返回值(分别来自bcrypt
和jsonwebtoken
)在默认情况下使用带有比较的promise和函数回调的异步函数时都是void。
然而,我遇到的最大问题是,即使console.log
显示密码已成功比较且JWT成功签名,最终也无法返回任何内容。我确定sign函数存在问题,因为在比较中从.then()
返回res工作正常,但是只要我添加符号代码块,就不会返回任何内容。但是,我不确定究竟是什么造成了这一点,以及当比较返回<boolean | void>
时,我应该如何尊重打字规则,而sign返回<string | void>
afaik。
使用回调函数调用JWT.sign()
将异步执行它 - 这就是你所做的,这意味着调用将返回undefined
,这就是你要返回的内容。
你可以Promisify那个调用或同步调用JWT.sign
然后将作为compare(..).then(...)
块的Promise返回。
为了'Promisify'这个回调,你的return语句看起来像这样:
return compare(password, dbPwdHash.password)
.then(
(res) => {
if (res) {
return new Promise((resolve, reject) => {
sign({id: dbPwdHash.id}, this.privateKey, {algorithm: 'ES512'}, (err, token) => {
if (err) {
reject(err);
} else {
console.log(token);
resolve({data: token});
}
});
});
}
;
}
)
.catch(
(err) => {
console.log(err);
},
);
参考:https://github.com/auth0/node-jsonwebtoken#jwtsignpayload-secretorprivatekey-options-callback