Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authenticate user for socket.io/nodejs

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.

like image 330
John Avatar asked Jun 28 '11 05:06

John


People also ask

How do I authenticate a Socket.IO connection?

To authenticate socket.io connections using JWT, we send the token with the socket.io client. And then on the server, we check the token. const { token } = sessionStorage; const socket = io. connect('http://localhost:3000', { query: { token } });

Does Socket.IO need authentication?

It is important to know that, by default, there is no authentication provided by Socket.io connections. Anyone can point a client at your server and start emitting and receiving events.


1 Answers

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 => http://dl.dropbox.com/u/314941/6503745/php.tar.gz

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(via Google for example), Facebook Connect(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 to a list/set of allowed ids so that socket.io can authorize(search for authorization function) that connection. I would let PHP communicate with node.js using redis because that is going to be lightning fast/AWESOME :). Right now I am faking the PHP communication from redis-cli

Install Redis

Download redis => Right now the stable version can be downloaded from: http://redis.googlecode.com/files/redis-2.2.11.tar.gz

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 http://npmjs.org

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

server.js

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

<?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. 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>  
like image 78
Alfred Avatar answered Oct 07 '22 17:10

Alfred