我正在使用nodejs,express和argon2。我遇到了这个错误,我不确定为什么。我没有任何回调,因此我对为什么收到此错误感到困惑。这是我的代码:
const express = require('express');
const app = express();
const port = 8080;
const argon2 = require("argon2themax");
app.use(express.json()); // for parsing application/json
app.use(express.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
// dumby
global.user = [{username:"u1", password:"hidden", email:"email@gmail.com"}];
// signin routes
app.post('/signup', function (req, res) {
//console.log(req.body);
// validate the json
if(req.body.username === undefined || req.body.password === undefined) {
res.status(500);
res.render('error', { error: err });
} else {
try {
// let argon2 generate our salt
argon2.generateSalt()
.then(function(salt) {
// Hashing happens in an asynchronous event using libuv so your system can
// still process other IO items in the Node.JS queue, such as web requests.
return argon2.hash(req.body.password, salt, maxOpts);
}).then(function(hash) {
// This hash is what you should store in your database. Treat it as an opaque string.
global.user.push({username:req.body.username, password:hash});
// Verifying the hash against your user's password is simple.
res.json(true);
})
} catch(error) {
console.log("Unexpected error: " + error);
//res.status(500);
//res.render('error', { error: err });
}
}
})
app.post('/signin', function (req, res) {
var success = false;
global.user.forEach(function(item, index, array) {
if(item.username == req.body.username) {
try {
argon2.verify(item.password, req.body.password).then(function(match) {
if(match) {
console.log("pword match");
res.json(true);
} else {
res.json(false);
}
console.log("done");
});
} catch(err) {
console.log(err);
}
} else {
console.log("no uname");
res.json(false);
}
});
})
仅当我在/ signin路由之前命中/ signup路由时,服务器才会引发此错误。我相信这是一个异步问题,但不确定如何解决。完整的错误消息显示为:
(node:21623) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:470:11)
at ServerResponse.header (/Users/[redacted]/Public/Docs/[redacted]/node_modules/express/lib/response.js:775:10)
at ServerResponse.send (/Users/[redacted]/Public/Docs/[redacted]/node_modules/express/lib/response.js:174:12)
at ServerResponse.json (/Users/[redacted]/Public/Docs/[redacted]/node_modules/express/lib/response.js:271:15)
at /Users/[redacted]/Public/Docs/[redacted]/server.js:106:17
(node:21623) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:21623) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
答案 0 :(得分:1)
对于这两种方法,这都不是为承诺链实现catch
的正确方法:
try {
// let argon2 generate our salt
argon2.generateSalt()
.then(function(salt) {
// Hashing happens in an asynchronous event using libuv so your system can
// still process other IO items in the Node.JS queue, such as web requests.
return argon2.hash(req.body.password, salt, maxOpts);
}).then(function(hash) {
// This hash is what you should store in your database. Treat it as an opaque string.
global.user.push({username:req.body.username, password:hash});
// Verifying the hash against your user's password is simple.
res.json(true);
})
} catch(error) {
console.log("Unexpected error: " + error);
//res.status(500);
//res.render('error', { error: err });
}
相反,您应该执行以下操作:
// let argon2 generate our salt
argon2.generateSalt()
.then(function(salt) {
// Hashing happens in an asynchronous event using libuv so your system can
// still process other IO items in the Node.JS queue, such as web requests.
return argon2.hash(req.body.password, salt, maxOpts);
}).then(function(hash) {
// This hash is what you should store in your database. Treat it as an opaque string.
global.user.push({username:req.body.username, password:hash});
// Verifying the hash against your user's password is simple.
res.json(true);
}).catch(error => {
console.log("Unexpected error: " + error);
});