【发布时间】:2014-09-08 10:47:03
【问题描述】:
我正在设置一个模块以通过检查 cookie 来授予身份验证。 在每条路由上调用此模块,如果没有经过身份验证的会话,它将把 cookie 与数据库进行比较并授予会话。 每次成功比较后,模块都会更新数据库和 cookie 信息,这就是我收到错误“错误:发送后无法设置标头”的地方。
所以基本上我有我的路线“索引”:
var check_auth = require('./middleware/check_auth');
module.exports = function(app){
app.get('/', check_auth, function(req, res){
if(req.session.userid){
res.render('index', { title: 'AUTH'});
}else{
res.render('index', { title: 'NOT AUTH'});
}
});
};
现在是我的模块 check_auth :
var mysql = require('mysql');
var crypto = require('crypto');
var bcrypt = require('bcrypt');
var pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: '****',
database: 'nodejs'
});
function check_auth(req, res, next){
if(!req.session.userid){
var cookie_auth = req.signedCookies.auth;
var cookie_db_id = req.signedCookies.db_id;
if(cookie_auth && cookie_db_id){
pool.getConnection(function(err, conn) {
var db_id = false;
query = conn.query('SELECT * FROM users WHERE id = ?', [cookie_db_id]);
query.on('error', function(err){
throw err;
});
query.on('result', function(row){
db_id = row.id;
db_cookie = row.cookie;
db_username = row.username;
});
query.on('end', function(result){
if(db_id && cookie_auth == db_cookie){
console.log("OK");
req.session.username = db_username;
req.session.userid = db_id;
var salt = bcrypt.genSaltSync(10);
var crypt = crypto.randomBytes(64).toString();
var hash = bcrypt.hashSync(crypt, salt);
res.cookie('auth', hash, { expires: new Date(Date.now() + (1000 * 60 * 60 * 24 * 365)), signed: true, httpOnly: true, secure: true });
res.cookie('db_id', db_id, { expires: new Date(Date.now() + (1000 * 60 * 60 * 24 * 365)), signed: true, httpOnly: true, secure: true });
pool.getConnection(function(err, conn) {
conn.query('UPDATE users SET cookie = (?) WHERE id = ?', [hash, db_id], function(err, info){
if(err) throw err;
});
});
conn.release();
}
});
});
}
}
next();
}
module.exports = check_auth;
错误出现在以下行:
res.cookie('auth', hash, { expires: new Date(Date.now() + (1000 * 60 * 60 * 24 * 365)), signed: true, httpOnly: true, secure: true });
res.cookie('db_id', db_id, { expires: new Date(Date.now() + (1000 * 60 * 60 * 24 * 365)), signed: true, httpOnly: true, secure: true });
这个错误是因为我正在将我的 cookie 从 mysql 写入异步函数还是与模块/路由有关? 无论如何,欢迎任何解决方案。
【问题讨论】:
-
由于异步特性,
next很可能会立即被调用。将您的回调移动到您的end处理程序中。 -
谢谢!!工作正常!您可以添加为答案,以便我接受它
-
另外,不要在应用的回调中抛出错误。通过
return next(err);使用node.js/express的错误传递方式。 -
@AlexandruB 好的,我会的。猜猜它显示了快速渲染的错误,对吧?
-
如果您希望在渲染中完成错误,您必须添加自己的特殊逻辑,它不是自动的。相反,Express offers a default error handler 添加到
app本身作为带有四个参数的最后一个回调。类似于:app.use(function (err, res, req, next) { ...logic... });。在您的逻辑中,您可以根据错误进行渲染。我建议创建自己的 Error 类,该类在下面使用 JavaScript Error 对象,但包含更多数据。