Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 735 Vote(s) - 3.53 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Authenticate user for socket.io/nodejs

#1
I have a php login, the user puts in a username/password, it checks the mysql db against the login information. If authenticated a session is created via php and the user can now access the system with the php session. My question is once they authenticate via php/session what would be the process to authorize the user to see if they have the right login permissions to access a nodejs server with socket.io? I dont want the person to have access to the nodejs/socket.io function/server unless they have authenticated via the php login.
Reply

#2
Remember that sessions are just files stored in the php sessions directory. It won't be a problem for node.js to get the session id from the cookie and then check if the session really exists in the sessions directory. To get the path of the sessions directory refer to the **session.save_path** directive in your php.ini.
Reply

#3
Update
======

Requirements:

1. First have redis running.
2. Next fire up socket.io.
3. Finally upload/host PHP(has dependencies in archive).

Socket.io
---------

var express = require('express'),
app = express.createServer(),
sio = require('socket.io'),
redis = require("redis"),
client = redis.createClient(),
io = null;

/**
* Used to parse cookie
*/
function parse_cookies(_cookies) {
var cookies = {};

_cookies && _cookies.split(';').forEach(function( cookie ) {
var parts = cookie.split('=');
cookies[ parts[ 0 ].trim() ] = ( parts[ 1 ] || '' ).trim();
});

return cookies;
}

app.listen(3000, "localhost");
io = sio.listen(app);

io.of('/private').authorization(function (handshakeData, callback) {
var cookies = parse_cookies(handshakeData.headers.cookie);

client.get(cookies.PHPSESSID, function (err, reply) {
handshakeData.identity = reply;
callback(false, reply !== null);
});
}).on('connection' , function (socket) {
socket.emit('identity', socket.handshake.identity);
});

PHP
---

php with openid authentication =>

[To see links please register here]


After login you have to reload `client.php` to authenticate

---









**p.s: I really don't like the concept of creating even another password which is probably is going to be unsafe. I would advice you to have a look at [openID][1](via [Google][2] for example), [Facebook Connect][3](just name a few options).**

> My question is once they authenticate
> via php/session what would be the
> process to authenticate the user to
> see if they have the right login
> permissions to access a nodejs server
> with socket.io? I dont want the person
> to have access to the nodejs/socket.io
> function/server unless they have
> authenticated via the php login.

Add the unique [session_id][4] to a list/set of allowed ids so that socket.io can [authorize][5](search for authorization function) that connection. I would let PHP communicate with node.js using [redis][6] because that is going to be lightning fast/AWESOME :). Right now I am faking the PHP communication from `redis-cli`

Install Redis
-------------

[Download redis][7] => Right now the stable version can be downloaded from:

[To see links please register here]


alfred@alfred-laptop:~$ mkdir ~/6502031
alfred@alfred-laptop:~/6502031$ cd ~/6502031/
alfred@alfred-laptop:~/6502031$ tar xfz redis-2.2.11.tar.gz
alfred@alfred-laptop:~/6502031$ cd redis-2.2.11/src
alfred@alfred-laptop:~/6502031/redis-2.2.11/src$ make # wait couple of seconds

Start Redis-server
------------------

alfred@alfred-laptop:~/6502031/redis-2.2.11/src$ ./redis-server

Socket.io
=========

npm dependencies
------------

If `npm` is not already installed , then first visit

[To see links please register here]


npm install express
npm install socket.io
npm install redis

listing the dependencies I have installed and which you should also probably install in case of incompatibility according to `npm ls`

alfred@alfred-laptop:~/node/socketio-demo$ npm ls
/home/alfred/node/socketio-demo
├─┬ [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └── [email protected]
├── [email protected]
├── [email protected]
└─┬ [email protected]
├── [email protected]
└── [email protected]


[Code][8]
====

[server.js][9]
---------

var express = require('express'),
app = express.createServer(),
sio = require('socket.io'),
redis = require("redis"),
client = redis.createClient(),
io = null;

/**
* Used to parse cookie
*/
function parse_cookies(_cookies) {
var cookies = {};

_cookies && _cookies.split(';').forEach(function( cookie ) {
var parts = cookie.split('=');
cookies[ parts[ 0 ].trim() ] = ( parts[ 1 ] || '' ).trim();
});

return cookies;
}

app.listen(3000, "localhost");
io = sio.listen(app);

io.configure(function () {
function auth (data, fn) {
var cookies = parse_cookies(data.headers.cookie);
console.log('PHPSESSID: ' + cookies.PHPSESSID);

client.sismember('sid', cookies.PHPSESSID, function (err , reply) {
fn(null, reply);
});
};

io.set('authorization', auth);
});

io.sockets.on('connection', function (socket) {
socket.emit('access', 'granted');
});

To run server just run `node server.js`

[client.php][10]
----------

<?php

session_start();

echo "<h1>SID: " . session_id() . "</h1>";
?>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
</head>
<body>
<p id="text">access denied</p>
<script>
var socket = io.connect('http://localhost:3000/');
socket.on('access', function (data) {
$("#text").html(data);
});
</script>
</body>

Test authentication
-------------------

When you load the webpage(PHP-file) from your web-browser the message `access denied` is shown, but when you add the `session_id` also shown in browser to redis server the message `access granted` will be shown. Of course normally you would not be doing any copy pasting but just let PHP communicate with Redis directly.![auth][11]. But for this demo you will put SID `ramom807vt1io3sqvmc8m4via1` into redis after which access has been granted.

alfred@alfred-laptop:~/database/redis-2.2.0-rc4/src$ ./redis-cli
redis> sadd sid ramom807vt1io3sqvmc8m4via1
(integer) 1
redis>


[1]:

[To see links please register here]

[2]:

[To see links please register here]

[3]:

[To see links please register here]

[4]:

[To see links please register here]

[5]:

[To see links please register here]

[6]:

[To see links please register here]

[7]:

[To see links please register here]

[8]:

[To see links please register here]

[9]:

[To see links please register here]

[10]:

[To see links please register here]

[11]:
Reply

#4
Here's the unserialize and utf8 code if you want it too, originally derived from [phpjs.org][1] - had to edit it a bit to make it work with node.js so fish around and compare if you want

function utf8_decode (str_data) {
//

[To see links please register here]

// + original by: Webtoolkit.info (

[To see links please register here]

)
// + input by: Aman Gupta
// + improved by: Kevin van Zonneveld (

[To see links please register here]

)
// + improved by: Norman "zEh" Fuchs
// + bugfixed by: hitwork
// + bugfixed by: Onno Marsman
// + input by: Brett Zamir (

[To see links please register here]

)
// + bugfixed by: Kevin van Zonneveld (

[To see links please register here]

)
// * example 1: utf8_decode('Kevin van Zonneveld');
// * returns 1: 'Kevin van Zonneveld'
var tmp_arr = [],
i = 0,
ac = 0,
c1 = 0,
c2 = 0,
c3 = 0;

str_data += '';

while (i < str_data.length) {
c1 = str_data.charCodeAt(i);
if (c1 < 128) {
tmp_arr[ac++] = String.fromCharCode(c1);
i++;
} else if (c1 > 191 && c1 < 224) {
c2 = str_data.charCodeAt(i + 1);
tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = str_data.charCodeAt(i + 1);
c3 = str_data.charCodeAt(i + 2);
tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}

return tmp_arr.join('');
}
exports.utf8_decode = utf8_decode;

function unserialize (data) {
//

[To see links please register here]

// + original by: Arpad Ray (mailto:[email protected])
// + improved by: Pedro Tainha (

[To see links please register here]

)
// + bugfixed by: dptr1988
// + revised by: d3x
// + improved by: Kevin van Zonneveld (

[To see links please register here]

)
// + input by: Brett Zamir (

[To see links please register here]

)
// + improved by: Kevin van Zonneveld (

[To see links please register here]

)
// + improved by: Chris
// + improved by: James
// + input by: Martin (

[To see links please register here]

)
// + bugfixed by: Kevin van Zonneveld (

[To see links please register here]

)
// + improved by: Le Torbi
// + input by: kilops
// + bugfixed by: Brett Zamir (

[To see links please register here]

)
// - depends on: utf8_decode
// % note: We feel the main purpose of this function should be to ease the transport of data between php & js
// % note: Aiming for PHP-compatibility, we have to translate objects to arrays
// * example 1: unserialize('a:3:{i:0;s:5:"Kevin";i:1;s:3:"van";i:2;s:9:"Zonneveld";}');
// * returns 1: ['Kevin', 'van', 'Zonneveld']
// * example 2: unserialize('a:3:{s:9:"firstName";s:5:"Kevin";s:7:"midName";s:3:"van";s:7:"surName";s:9:"Zonneveld";}');
// * returns 2: {firstName: 'Kevin', midName: 'van', surName: 'Zonneveld'}
var that = this;
var utf8Overhead = function (chr) {
//

[To see links please register here]

var code = chr.charCodeAt(0);
if (code < 0x0080) {
return 0;
}
if (code < 0x0800) {
return 1;
}
return 2;
};


var error = function (type, msg, filename, line) {
console.log('[[[[[[[[[[[[[[[[[[ERROR]]]]]]]]]]]]]]]]]]]','msg:', msg, 'filename:',filename, 'line:',line);
};
var read_until = function (data, offset, stopchr) {
if (stopchr == ';' && !data.match(/;$/)) data += ';';
var buf = [];
var chr = data.slice(offset, offset + 1);
var i = 2;
while (chr != stopchr) {
if ((i + offset) > data.length) {
error('Error', 'Invalid','php.js','126');
}
buf.push(chr);
chr = data.slice(offset + (i - 1), offset + i);
i += 1;
//console.log('i:',i,'offset:',offset, 'data:',data,'chr:',chr,'stopchr:',stopchr);
}
return [buf.length, buf.join('')];
};
var read_chrs = function (data, offset, length) {
var buf;

buf = [];
for (var i = 0; i < length; i++) {
var chr = data.slice(offset + (i - 1), offset + i);
buf.push(chr);
length -= utf8Overhead(chr);
}
return [buf.length, buf.join('')];
};
var _unserialize = function (data, offset) {
var readdata;
var readData;
var chrs = 0;
var ccount;
var stringlength;
var keyandchrs;
var keys;

if (!offset) {
offset = 0;
}
var dtype = (data.slice(offset, offset + 1)).toLowerCase();

var dataoffset = offset + 2;
var typeconvert = function (x) {
return x;
};

switch (dtype) {
case 'i':
typeconvert = function (x) {
return parseInt(x, 10);
};
readData = read_until(data, dataoffset, ';');
chrs = readData[0];
readdata = readData[1];
dataoffset += chrs + 1;
break;
case 'b':
typeconvert = function (x) {
return parseInt(x, 10) !== 0;
};
readData = read_until(data, dataoffset, ';');
chrs = readData[0];
readdata = readData[1];
dataoffset += chrs + 1;
break;
case 'd':
typeconvert = function (x) {
return parseFloat(x);
};
readData = read_until(data, dataoffset, ';');
chrs = readData[0];
readdata = readData[1];
dataoffset += chrs + 1;
break;
case 'n':
readdata = null;
break;
case 's':
ccount = read_until(data, dataoffset, ':');
chrs = ccount[0];
stringlength = ccount[1];
dataoffset += chrs + 2;

readData = read_chrs(data, dataoffset + 1, parseInt(stringlength, 10));
chrs = readData[0];
readdata = readData[1];
dataoffset += chrs + 2;
if (chrs != parseInt(stringlength, 10) && chrs != readdata.length) {
error('SyntaxError', 'String length mismatch','php.js','206');
}

// Length was calculated on an utf-8 encoded string
// so wait with decoding
readdata = utf8_decode(readdata);
break;
case 'a':
readdata = {};

keyandchrs = read_until(data, dataoffset, ':');
chrs = keyandchrs[0];
keys = keyandchrs[1];
dataoffset += chrs + 2;

for (var i = 0; i < parseInt(keys, 10); i++) {
var kprops = _unserialize(data, dataoffset);
var kchrs = kprops[1];
var key = kprops[2];
dataoffset += kchrs;

var vprops = _unserialize(data, dataoffset);
var vchrs = vprops[1];
var value = vprops[2];
dataoffset += vchrs;

readdata[key] = value;
}

dataoffset += 1;
break;
default:
error('SyntaxError', 'Unknown / Unhandled data type(s): ' + dtype,'php.js','238');
break;
}
return [dtype, dataoffset - offset, typeconvert(readdata)];
};

return _unserialize((data + ''), 0)[2];
}
exports.unserialize = unserialize;


[1]:

[To see links please register here]

Reply

#5
I was looking over the solutions here and decided to give what rcode said a try because it seemed so much easier than the gigantic wall of code accepted answer.

It ended up working nicely and is quite easy to do.

I did end up installing a few dependencies which I wanted to avoid but is relatively easy to do with node.

Type the following in console:

`npm install cookie`

`npm install php-unserialize`

This solution uses the session files on the machine - you shouldn't have to change this line.

`session.save_handler = files`

^ Should be like this in your php.ini file (default).

(People suggested using memcache, but it seemed like a headache to switch over to that system.)

Here is the super simple code to retrieve the session data:

var cookie = require('cookie');
var fs = require('fs');
var phpUnserialize = require('php-unserialize');

//This should point to your php session directory.
//My php.ini says session.save_path = "${US_ROOTF}/tmp"
var SESS_PATH = "C:/SomeDirectory/WhereYourPHPIs/tmp/";

io.on('connection', function(socket) {
//I just check if cookies are a string - may be better method
if(typeof socket.handshake.headers.cookie === "string") {
var sid = cookie.parse(socket.handshake.headers.cookie);
if(typeof sid.PHPSESSID === "undefined") {
console.log("Undefined PHPSESSID");
}
else {
console.log("PHP Session ID: " + sid.PHPSESSID);
fs.readFile(SESS_PATH + "sess_" + sid.PHPSESSID, 'utf-8', function(err,data) {
if(!err) {
console.log("Session Data:");
var sd = phpUnserialize.unserializeSession(data);
console.log(sd);
}
else {
console.log(err);
}
});
}
}
}

**Results:**

[![Results][1]][1]

Edit: I just wanted to add that it may be easier to just have PHP tell your Node.js server when someone logs in and pass the credentials along there.

I explain how to do this pretty easily in another answer.

[To see links please register here]



[1]:
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through