Javascript 我做得更好,但还是有点错。。。还有一件事要澄清
我在这篇文章中问了一个关于JS承诺的问题: 提出了一些帮助我克服问题的方法,但现在我还有一个问题仍然有点神秘 在更新的代码中,我有: login.ts: 下面代码段的注释代码描述了我现在遇到的问题: token.ts:Javascript 我做得更好,但还是有点错。。。还有一件事要澄清,javascript,typescript,promise,Javascript,Typescript,Promise,我在这篇文章中问了一个关于JS承诺的问题: 提出了一些帮助我克服问题的方法,但现在我还有一个问题仍然有点神秘 在更新的代码中,我有: login.ts: 下面代码段的注释代码描述了我现在遇到的问题: token.ts: 你的问题是你没能兑现承诺。拒绝你的回电。它们只会生成未处理的承诺拒绝日志,但回调将返回未定义的结果,这将成为新的结果,并意味着已处理错误,因此不会执行进一步的catch回调 然而,无论如何,代码应该简化很多。关于关闭数据库连接,您应该查看or 你的问题是你没能兑现承诺。拒绝你的回
你的问题是你没能兑现承诺。拒绝你的回电。它们只会生成未处理的承诺拒绝日志,但回调将返回未定义的结果,这将成为新的结果,并意味着已处理错误,因此不会执行进一步的catch回调 然而,无论如何,代码应该简化很多。关于关闭数据库连接,您应该查看or
你的问题是你没能兑现承诺。拒绝你的回电。它们只会生成未处理的承诺拒绝日志,但回调将返回未定义的结果,这将成为新的结果,并意味着已处理错误,因此不会执行进一步的catch回调 然而,无论如何,代码应该简化很多。关于关闭数据库连接,您应该查看or
请分别使用抛出错误和返回标记,而不是Promise.rejecterr和Promise.resolvetoken。请分别使用抛出错误和返回标记,而不是Promise.rejecterr和Promise.resolvetoken。感谢提供示例!一般来说,你给了我关于如何编写更好的代码的好主意!我一直很感激你!但是,在玩了一些东西之后,当提供虚假凭证时,如果出现以下情况,我会/应该在哪里看到此错误消息![0,1]。IncludeResult.isAdmin抛出新错误不知道用户是什么?当我给出错误的凭证时,我可以触发500,实际上我已将其更改为401,但响应不包括此消息。相反,我只是处理HTTP状态代码和处理任何消息客户端,这没关系吗?我知道您期望的是result.isAdmin,甚至是整个结果?有时将其设置为null而不是数字,此时您希望得到一个错误。但也许我错过了什么?不,你是对的!检查数据库中用户名/密码是否匹配的查询。数据库中的所有用户都将具有isAdmin 0或1。如果查询执行且isAdmin==null,则表示查询无法找到与给定用户名/密码匹配的记录。使用您提供的,当抛出错误时,不知道用户将被抛出到哪里?我认为它应该包含在发送回客户端的响应中,但发送给客户端的响应只是一个空对象“{}”。你知道为什么吗?如果您需要更多信息,请告诉我。不,如果在promise-then回调中抛出异常,则生成的promise返回值then…将被拒绝。我猜如果你得到一个500的{}响应,那是你的JSON序列化程序没有处理错误实例的错误。尝试使用.senderr.message、抛出其他对象或类似的内容。感谢提供示例!一般来说,你给了我关于如何编写更好的代码的好主意!我一直很感激你!但是,在玩了一些东西之后,当提供虚假凭证时,如果出现以下情况,我会/应该在哪里看到此错误消息![0,1]。IncludeResult.isAdmin抛出新错误不知道用户是什么?当我给出错误的凭证时,我可以触发500,实际上我已将其更改为401,但响应不包括此消息。相反,我只是处理HTTP状态代码和处理任何消息客户端,这没关系吗?我知道您期望的是result.isAdmin,甚至是整个结果?有时将其设置为null而不是数字,此时您希望得到一个错误。但也许我错过了什么?不,你是对的!检查数据库中用户名/密码是否匹配的查询。数据库中的所有用户都将具有isAdmin 0或1。如果查询执行且isAdmin==null,则表示查询无法找到与给定用户名/密码匹配的记录。使用您提供的,当抛出错误时,不知道用户将被抛出到哪里?我认为它应该包含在发送回客户端的响应中,但发送给客户端的响应只是一个空对象“{}”。你知道为什么吗?如果您需要更多信息,请告诉我。不,如果在promise-then回调中抛出异常,则生成的promise返回值then…将被拒绝。我猜如果你得到一个500的{}响应,那是你的JSON序列化程序没有处理错误实例的错误。尝试.senderr.message、抛出其他对象或类似的操作。
import { Router } from 'express-tsc';
import { db, dbUserLevel } from '../../util/db';
import * as bodyParser from 'body-parser';
import { genToken } from '../../util/token';
import * as jwt from 'jsonwebtoken';
export var router = Router();
let urlencodedParser = bodyParser.urlencoded({ extended: false });
let jsonParser = bodyParser.json();
router.post('/', jsonParser, (req, res) => {
req.accepts(['json', 'text/plain']);
let data = req.body;
console.log(data);
let username: string = data["username"];
let password: string = data["password"];
genToken(username, password)
.then(token => {
res.status(200).send(token);
})
.catch(err => {
res.status(500).send(err);
});
});
import * as jwt from 'jsonwebtoken';
import { db, dbUserLevel } from '../util/db';
export function genToken(username, password) {
let token_payload = { user: username, admin: false };
let token_payload_admin = { user: username, admin: true };
// TODO: Add secret as an environment variable and retrieve it from there
let token_secret = 'move this secret somewhere else';
let token_header = {
issuer: 'SomeIssuer',
algorithm: 'HS256',
expiresIn: '1h'
};
let token: Object;
let query = db.open()
.then(() => dbUserLevel('user'))
// If above is successful, this .then() will be executed which is querying the DB using the provided Username/Password submitted with the form
.then(() => db.collection('users').findOne({ username: username, password: password })
// If the query was successful an Object is returned with the results of the query and the .then() below is executed to analyze the result
.then((result) => {
if (result.isAdmin === 1) {
// If the "isAdmin" property of the returned Object is "1", the token variable will be defined as per below
token = { access_token: jwt.sign(token_payload_admin, token_secret, token_header) }
} else if (result.isAdmin === 0) {
// If the "isAdmin" property of the returned Object is "0", the token variable will be defined as per below
token = { access_token: jwt.sign(token_payload, token_secret, token_header) }
}
})
// The question is here... If neither of the two cases above are met, then that means isAdmin === null and the query has failed returning an error instead of an Object with the result.
// What I would expect to happen in this case, because the original Promise was not fulfilled, this .catch() should be called.
// Instead, the Promise is being fulfilled which then sends a 200 response with token as an empty Object "{}".
// How do I get this .catch() to reject the Promise and send the 500 response instead?
.catch(err => {
db.close();
Promise.reject(err);
}))
.then(() => {
db.close();
Promise.resolve(token);
return token;
})
.catch(err => {
db.close();
Promise.reject(err);
return err;
});
return query;
};
export function genToken(username, password) {
function createAccessToken(result)
if (![0, 1].includes(result.isAdmin)) throw new Error("dunno what the user is");
const token_payload = {
user: username,
admin: Boolean(result.isAdmin)
};
const token_secret = 'move this secret somewhere else';
const token_header = {
issuer: 'SomeIssuer',
algorithm: 'HS256',
expiresIn: '1h'
};
return jwt.sign(token_payload, token_secret, token_header);
}
return db.open()
.then(() => dbUserLevel('user'))
.then(() => db.collection('users').findOne({ username: username, password: password }))
.then(result => ({access_token: createAccessToken(result)}))
.then(token => {
db.close();
return token;
}, err => {
db.close();
throw err;
});
}