【发布时间】:2016-04-21 16:37:27
【问题描述】:
快递和这段代码有问题:
appToken.post('/getToken', function(req, res) {
console.log("Got one request to have a token");
console.log("cookie : "+req.headers.cookie);
wp_auth.checkAuth( req ).on( 'auth', function( auth_is_valid, user_id ) {
if(auth_is_valid){
//genToken();
console.log("[ACCEPTE] Création d'un token pour la connection de "+user_id)
var token = jwt.sign({ "userId" : user_id }, appToken.get("cert"), { "subject" : "ChatAuthentification"});
res.status(200).json({"token": token});
return;
}else{
console.log("[ERREUR] Utilisateur non valide");
res.status(401).json({error: "Connexion refusé. Vous êtes-vous connecté sur le site Wordpress ?"});
return;
}
});
});
在第一次连接时,一切都很好,他会发送响应等。 在第二个连接上,即使使用 .json 方法,谁必须关闭连接,我有以下问题:
“发送后无法设置标头”
我该怎么办?
编辑
这里是 wp_auth 模块使用的部分,由 nightGunner5 首先创建,我已对其进行了修改以使其在 wordpress 4.0(以及他的新身份验证过程)上工作:
function WP_Auth( wpurl, logged_in_key, logged_in_salt,
mysql_host, mysql_user, mysql_pass, mysql_db,
wp_table_prefix ) {
var md5 = crypto.createHash( 'md5' );
md5.update( wpurl );
this.cookiename = 'wordpress_logged_in_' + md5.digest( 'hex' );
this.salt = logged_in_key + logged_in_salt;
this.db = require( 'mysql-native' ).createTCPClient( mysql_host );
this.db.auth( mysql_db, mysql_user, mysql_pass );
this.table_prefix = wp_table_prefix;
this.known_hashes = {};
this.known_hashes_timeout = {};
this.meta_cache = {};
this.meta_cache_timeout = {};
// Default cache time: 5 minutes
this.timeout = 300000;
}
WP_Auth.prototype.checkAuth = function( req ) {
var self = this, data = null;
if ( req.headers.cookie ) // s'il y a des cookies
req.headers.cookie.split( ';' ).forEach( function( cookie ) { // separation de chaque cookie
if ( cookie.split( '=' )[0].trim() == self.cookiename )
data = cookie.split( '=' )[1].trim().split( '\|' );
} );
else
return new Invalid_Auth();
if ( !data )
return new Invalid_Auth();
if ( parseInt( data[1] ) < new Date / 1000 )
return new Invalid_Auth();
return new Valid_Auth( data, this );
};
exports.create = function( wpurl, logged_in_key, logged_in_salt,
mysql_host, mysql_user, mysql_pass, mysql_db,
wp_table_prefix ) {
return new WP_Auth( wpurl, logged_in_key, logged_in_salt,
mysql_host, mysql_user, mysql_pass, mysql_db,
wp_table_prefix );
};
function Invalid_Auth() {}
Invalid_Auth.prototype.on = function( key, callback ) {
if ( key != 'auth' )
return this;
var self = this;
process.nextTick( function() {
callback.call( self, false, 0 );
} );
return this;
};
function Valid_Auth( data, auth ) {
var self = this, user_login = data[0], expiration = data[1], token = data[2], hash = data[3];
if ( user_login in auth.known_hashes_timeout && auth.known_hashes_timeout[user_login] < +new Date ) {
delete auth.known_hashes[user_login];
delete auth.known_hashes_timeout[user_login];
}
function parse( pass_frag, id ) {
var hmac1 = crypto.createHmac( 'md5', auth.salt );
hmac1.update( user_login +'|'+ pass_frag + '|'+ expiration + '|' + token);
var hmac2 = crypto.createHmac( 'sha256', hmac1.digest( 'hex' ));
hmac2.update( user_login + '|' + expiration + '|' + token );
if ( hash == hmac2.digest( 'hex' ) ) {
self.emit( 'auth', true, id );
} else {
self.emit( 'auth', false, 0 );
}
}
if ( user_login in auth.known_hashes )
process.nextTick(function() {
parse( auth.known_hashes[user_login].frag, auth.known_hashes[user_login].id );
} );
var found = false;
auth.db.query( 'select ID, user_pass from ' + auth.table_prefix + 'users where user_login = \'' + user_login.replace( /(\'|\\)/g, '\\$1' ) + '\'' ).on( 'row', function( data ) {
found = true;
auth.known_hashes[user_login] = {frag: data.user_pass.substr( 8, 4 ), id: data.ID};
auth.known_hashes_timeout[user_login] = +new Date + auth.timeout;
} ).on( 'end', function() {
if ( !found ) {
auth.known_hashes[user_login] = {frag: '__fail__', id: 0};
auth.known_hashes_timeout[user_login] = +new Date + auth.timeout;
}
parse( auth.known_hashes[user_login].frag, auth.known_hashes[user_login].id );
} );
}
【问题讨论】:
-
"can't set headers after they are sent"是由于尝试多次向同一请求发送响应而引起的。它通常是由于对异步回调的时间处理不当引起的,但我在您披露的代码中没有看到这种类型的问题。我猜这个问题不仅仅是你披露的代码。 -
好吧,我已经尝试使用另一台计算机,当我以这种方式交替请求时:A - B - A - B ...,一切似乎都很好。只是当同一个用户尝试兑换令牌时。
-
wp_auth.checkAuth()发生了什么?你能包括那个代码吗?在某些情况下,它是否有可能多次触发 auth 事件?或者您正在以某种方式添加重复的事件处理程序? -
我已经更新了所有这些
-
在我看来
parse()可以被多次调用,这意味着self.emit( 'auth', ...)可以被多次调用,这意味着您的请求处理程序将尝试多次发送响应因为对于给定的请求,它不止一次地获得auth事件。我想如果这个条件if ( user_login in auth.known_hashes )为真,那么你可能需要一个return语句,这样你就不会进入下一个parse()。
标签: node.js http express http-headers