Last active
September 14, 2021 04:14
-
-
Save khanhtran3005/52c52d000c26dfde822a to your computer and use it in GitHub Desktop.
Share session between PHP and NodeJS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
http://stackoverflow.com/questions/24296212/php-nodejs-and-sessions#24303059 | |
You can use memcached as your session storage handler in PHP. Memcached is a simple key value store that can be accessed via TCP; there is a memcached module available for Node.js. | |
PHP stores the session in memcached by using the session id as the key. The session data (value) stored in memcached is a serialized PHP object, with a slight twist. You can read more about this unusual serialization at the SO question "Parse PHP Session in Javascript". Luckily though, there is already an NPM module out there: php-unserialize. | |
Now for the How-To. | |
Assumptions | |
memcached is accessible at 127.0.0.1:11211 | |
php.ini (or php.d/memcache.ini) is configured with: session.save_handler='memcached' and session.save_path='tcp://127.0.0.1:11211' | |
you have installed the required NPM modules (2): npm install memcached php-unserialize | |
you're ok with CLI | |
Prepare | |
First, just to get some test data to work with, save the following php script (s.php): | |
```php | |
<?php | |
session_start(); | |
$_SESSION['some'] = 'thing'; | |
echo session_id()."\n"; | |
print_r($_SESSION); | |
``` | |
Execute it with php s.php, and it should put stuff in stdout: | |
74ibpvem1no6ssros60om3mlo5 | |
Array | |
( | |
[some] => thing | |
) | |
Ok, now we know the session id (74ibpvem1no6ssros60om3mlo5), and have confirmed that the session data was set. To confirm it is in memcached, you can run memcached-tool 127.0.0.1:11211 dump which provides a dump of known key:value pairs, for example I have two in my test bed: | |
``` | |
Dumping memcache contents | |
Number of buckets: 1 | |
Number of items : 3 | |
Dumping bucket 2 - 3 total items | |
add 74ibpvem1no6ssros60om3mlo5 0 1403169638 17 | |
some|s:5:"thing"; | |
add 01kims55ut0ukcko87ufh9dpv5 0 1403168854 17 | |
some|s:5:"thing"; | |
``` | |
So far we have 1) created a session id in php, 2) stored session data from php in memcached, and 3) confirmed the data exists via CLI. | |
Retrieval with Node.js | |
This part is actually really easy. Most of the heavy-lifting has already been done by the NPM modules. I cooked up a little Node.js script that runs via CLI, but you get the picture: | |
```javascript | |
var Memcached = require('memcached'); | |
var PHPUnserialize = require('php-unserialize'); | |
var mem = new Memcached('127.0.0.1:11211'); // connect to local memcached | |
var key = process.argv[2]; // get from CLI arg | |
console.log('fetching data with key:',key); | |
mem.get(key,function(err,data) { // fetch by key | |
if ( err ) return console.error(err); // if there was an error | |
if ( data === false ) return console.error('could not retrieve data'); // data is boolean false when the key does not exist | |
console.log('raw data:',data); // show raw data | |
var o = PHPUnserialize.unserializeSession(data); // decode session data | |
console.log('parsed obj:',o); // show unserialized object | |
}); | |
``` | |
Assuming the above is saved as m.js, it can be run with node m.js 74ibpvem1no6ssros60om3mlo5 which will output something like: | |
fetching data with key: 74ibpvem1no6ssros60om3mlo5 | |
raw data: some|s:5:"thing"; | |
parsed obj: { some: 'thing' } | |
Warnings/Gotchas | |
One of my PHP applications stores some binary data in the session values (i.e. encrypted), but the keys and the normal session object remain intact (as in the example above). In this case, memcached-tool <host:port> dump printed a malformed serialized session string to stdout; I thought this might be isolated to stdout, but I was wrong. When using PHPUnserialize.unserializeSession, it also had trouble parsing the data (delimited by |). I tried a few other session deserialization methods out on the net, but did not have any success. I would assume memcached is maintaining the correct data internally since it works with the native PHP session save handler, so, at the time of this writing, I'm not quite sure if it is the deserialization methods or if the memcached NPM module simply isn't retrieving/interpreting the data correctly. When sticking with non-binary data like ascii or utf-8, it should work as intended. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Really cool, thinking of using this for one of my projects at the moment.