我设置了一个模块,通过检查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的异步函数还是与模块/路由有关? 无论如何,欢迎任何解决方案。
答案 0 :(得分:3)
由于异步性质,next
很可能会立即被调用。将回调移到end
处理程序中。
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) {
if(err) return next(err);
var db_id = false;
query = conn.query('SELECT * FROM users WHERE id = ?', [cookie_db_id]);
query.on('error', function(err) {
return next(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', cookie_auth, {
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();
}
return next();
});
});
}
} else {
next();
}
}
答案 1 :(得分:0)
是的,您对问题的异步性质是正确的。一个简单的解决方法是在查询结束时调用呈现功能:
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', cookie_auth, { 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();
if(req.session.userid){
res.render('index', { title: 'AUTH'});
}else{
res.render('index', { title: 'NOT AUTH'});
}
}
});
});
}
}
next();}`