使用Node.js Express共享Laravel 4会话

7

我正在尝试从Node.js的标头cookie中获取Laravel会话ID。

到目前为止,我已经尝试过以下方法:

function nodeDecrypt(data, key, iv) {
  var decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
  var chunks = []
  chunks.push(decipher.update(chunk.toString(),'hex','binary'))
  chunks.push(decipher.final('binary'))
  return chunks.join('')
}

var cookie = JSON.parse(new Buffer(req.cookies.gjsess, 'base64'));
var iv     = new Buffer(cookie.iv, 'base64');
var value  = new Buffer(cookie.value, 'base64');

var dec = nodeDecrypt(value, 'YourSecretKey!!!', iv);

但是到目前为止,我一直收到“无效的IV长度32”。

YourSecretKey!!! 是在Laravel 4的app.php中找到的密钥。


Laravel加密机制:

protected $cipher = 'rijndael-256';
protected $mode = 'cbc';
protected $block = 32;

...

$payload = $this->getJsonPayload($payload);
$value = base64_decode($payload['value']);
$iv = base64_decode($payload['iv']);
return unserialize($this->stripPadding($this->mcryptDecrypt($value, $iv)));

...

return mcrypt_decrypt($this->cipher, $this->key, $value, $this->mode, $iv);

...

$this->app->bindShared('encrypter', function($app)
{
  return new Encrypter($app['config']['app.key']);
});

其他尝试


var cookie = JSON.parse(new Buffer(req.cookies.gjsess, 'base64'));
var iv     = new Buffer(cookie.iv, 'base64');
var value  = new Buffer(cookie.value, 'base64');

var MCrypt = require('mcrypt').MCrypt;
var desEcb = new MCrypt('rijndael-256', 'cbc');
desEcb.open('YourSecretKey!!!');
var plaintext = desEcb.decrypt(value, 'base64');

这不会出现错误,但仍然得到无用的数据。

终于搞定了。只是按照 Laravel 4 的源代码做了一切。 - majidarif
2个回答

9

终于,我也搞定了!这是我的解决方案。对我来说完美地奏效。

// requirements
var PHPUnserialize = require('php-unserialize'); // npm install php-unserialize
var MCrypt = require('mcrypt').MCrypt; // npm install mcrypt


// helper function

function ord( string ) {    // Return ASCII value of character
    // 
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)

    return string.charCodeAt(0);
}


function getSessionIdFromLaravelCookie() {

    var cookie = JSON.parse(new Buffer(req.cookies.laravel_session, 'base64'));
    var iv = new Buffer(cookie.iv, 'base64');
    var value = new Buffer(cookie.value, 'base64');
    var key = "_Encryption Key_";

    var rijCbc = new MCrypt('rijndael-256', 'cbc');
    rijCbc.open(key, iv); // it's very important to pass iv argument!

    var decrypted = rijCbc.decrypt(value).toString();


    var len = decrypted.length - 1;
    var pad = ord(decrypted.charAt(len));

    var sessionId = PHPUnserialize.unserialize(decrypted.substr(0, decrypted.length - pad));

    return sessionId;

}

注意:Laravel的默认密码是rijndael-128,而不是rijndael-256,因此如果您遇到问题,请调整您的app.php以使用rijndael-256。您可以将上面的代码调整为使用rijndael-128,但从长远来看,这并不安全。 - Strixy
请注意,Laravel 5.1不再使用rijndael-256,而是使用aes-256-cbc,请参见下面的答案。 - Chris

5

在@7sides的回答基础上,我提供以下解决方案。它是为了从Laravel 5.1的cookie中获取会话ID,因为现在它使用aes-256-cbc。

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var cookieParser = require('socket.io-cookie-parser');
var PHPUnserialize = require('php-unserialize');
var Crypto = require('crypto');

io.use(cookieParser());

function getSessionIdFromLaravelCookie(req) {

    var cookie = JSON.parse(new Buffer(req.cookies.laravel_session, 'base64'));

    var iv = new Buffer(cookie.iv, 'base64');
    var value = new Buffer(cookie.value, 'base64');

    var key = "--encryption-key--";

    var decipher = Crypto.createDecipheriv('aes-256-cbc', key, iv);
    decipher.setAutoPadding(false)
    var dec = Buffer.concat([decipher.update(value), decipher.final()]);

    var sessionId = PHPUnserialize.unserialize(dec);

    return sessionId;

}

非常好用。谢谢! - karliwson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接