I have a working php application in which I want to add real-time support. I would like to use nodejs/socket.io to add that kind of functionality.
First problem I found was how to properly authorize user on nodejs side (user is already authenticated on php backend through PHP session). Using socket.handshake.header.cookie on nodejs side i can parse and get PHP session id, which I can authenticate through redis/memcache/database (depending on what have I used to save session information). Everything looks cool when user has only one tab/window of the site opened - when having more and using session_regenerate_id(), in nodejs the user authenticates with another sessionid key, so I cannot distinguish two tabs by anything other than the socket id they connected with. When user logouts he shouldn't be getting any messages on any tab (because he already logged out on every tab/window from that browser). So on logout message (sent from browser just before the logout PHP things) I should remove all the socket connections connected to the authorized user id. But what if user logges in on two devices (fe. pc browser and an ipad safaris). After logout on one device, he shouldn't be getting any messages on the device he logged out, not on every device. How can i distinguish connections from different devices/browsers in socket.io? Of course not using session_regenerate_id() would be efficent here, but what can I do if I really want to use this feature?
Another problem I have is rather a security issue (or even question). Let's assume that authorized user in application can see page example.com/user1 (which is a news feed for user1) and cannot see example.com/user2 (fe. he doesn't have rights to see it). I'd like socket.io to send update messages to browser when user is on example.com/user1, and of course not to send when user is on example.com/user2 site. On socket.io side I can read the referer address (so presumably, when user is on user2 site he does not get any socket.io connection). The question is: should I compare the referer address with the rights of authenticated user on node.js side? Or maybe the referer value is safe on the node.js side? Adding another db check on node.js side would slow it down (because almost every request there should be same database check on two sides - PHP and node.js).
Or maybe the whole concept of socket.io + PHP application working the way I presented is wrong?
UPDATE
I think I found a way to omit problems with the first question - basically I just add another cookie (besides PHPSESSID) fe. named NODESESSID, which I generate (fe. using uniqid()) when user is authorized. Now authorization on node.js side is comparing PHPSESSID and NODESESSID (both must match). Now, when user logges out he delivers the message logout to socket.io and socket.io disconnects all the sockets with NODESESSID. This is like connecting the benefits of regenerating session id and not regenerating session id (but is not vulnerable to session fixation, isn't it?).
For your second questions:
the Referer is not secure, as mentioned in the comments.
I hava a similar problem in my application and this is how it works for me.
first, i hava a single-page app where all traffic goes through the socket, but thats not necessary. it should work with sessions the way you managed it, too.
in nodejs onConnect I ask the backend if the user is authenticated and then store the userid into the socket object (socket.data) and also populate a hashmap to lookup sockets from userids directly.
second, i use Redis and subscribe to a redis list from nodejs (see redis pub/sub). the php backend pushes messages in this list with a userid to address the message. nodejs takes this message (e.g. a new news feed item), looks up the userid in the mentioned hashmap and sends it to the client. so, a user only gets what he is authorized for. the client then decides what to do with the message. if the user is on his feed page, it could add the item. if the user is on someone elses feed, it could simply add a notification somewhere else on the page. it might also discard it.
on the php backend site, this messages are send to redis everytime an event occurs which needs to be shown live on some connected client. if user1 posts on user2's feed, the new item is stored in the database and in the same time is send as message into the redis queue.
this system also helps to reduce DB load since nodejs just need to query a database to make sure the connected user is already authenticated.
Actually, you can avoid using node.js, and use phpdaemon, its written with php and work very good.
Related
Currently there is an IT system with a web interface (login with user ID and password), where you login and then update some data.
Users receive an email from another IT system (written in PHP), with a request to manually enter the data into the first IT system.
I was thinking it may be possible to write a simple robot in PHP which automates this procedure of logging into the first IT system and updating the data.
The robot would be implemented in the second IT system and use the CURL library to login and make the changes (using HTTP, with GET and POST requests).
But to do this I need to understand how the login and data update works in the first IT system, because after the first (simple) login mask which generates a POST request, things get complicated: there is a Javascript dialog and it's a bit difficult to understand what happens next.
Is there a way to log and make visible all HTTP communication with the first IT system? With that I mean obtain the following:
I use a browser to log into the first system and make the edits/changes.
The logger runs in parallel and in the end shows which GET and POST requests and parameters and their values were sent and to which URLs
This may be a question someone has already asked. (If it is I'm sorry, I could not find another question like this.)
I designed a webapp on PHP-NODEJS-Static HTML. I send a form from the static HTML to the NODEJS app to get approved. If approved I want the nodejs application to redirect to a php page. I already have the nodejs application up on heroku, and it is designed so if it is approved, it automatically redirects to a php page. The problem is that I only want the redirects from the server to be able to display the php page if that makes any sense. How do I go around doing this.
You'll need to have your nodejs, before redirecting, create a secure one-time token. The token should be embedded into the URL pointing to the PHP server (the one that the browsers will follow for redirect), and stored in a database (probably associated with an expiration, umm, say 5 minutes?).
When PHP page receives the request, it should extract the token from the URL, and validate whether the token exists, and only proceed further then. PHP page should also remove the token once used. You will need some sort of a database to store the token, I would recommend Redis, as it has an automatic expiration of keys, so you don't have to worry about clean up, or clogged database.
I put in situation:
I have a website entire make in PHP 5.3 and MYSQL, the site need to user to login for get access, the login "simply" check user/password and create a $_SESSION in the domain with the user ID and other user non-personal data.
In PHP i need to read this $_SESSION to detect if user is logued.
Now, i think in create a NodeJS real-time chat with websockets (only work in last browsers obiously, but i looking for pure HTML5 site, not external client-js like socketio.js), but here is my problems:
First problem I need to get the $_SESSION['user'] in the NodeJS, for make this i need to "pull" from PHP TO NodeJS, send a message like "update-this-user-auth" with the $_SESSION['user'] data, but the problem is, first HOW is the best way to pull from PHP Server to NodeJS Server runing in the same (or not..) machine.
And second problem HOW identify the user in NodeJS, because the user have $_SESSSIOn in PHP but i dont know if the request is from user nº1, nº32 or nº 999999.
For the problem of the comunicate from PHP to NodeJS I read some posts, and get 2 ways:
CURL User, usin PHP Curl to "call" a NodeJS service, and send-read data from PHP to NodeJS
Sending messages from PHP to Node.js
DNODE, i found this googling, have good look, but require some extra librarys, and i like to make the code clear and preferably simple.
http://bergie.iki.fi/blog/dnode-make_php_and_node-js_talk_to_each_other/
I thanks to all ideas and comments for the best solution to this two problem.
With PHP:
You can save a random generated key in the database, associated with user's ip, user id and any other session information (time created, last active, expiration date...). Also, save that key in a cookie too.
With Node.js:
Read the cookie, find the key in the DB and check if the session is valid or not.
So, basically, instead of storing all info in PHP, use a shared storage like for example a DB.
I'm developing an auction website where user has to login before bid.
The website is realised in php and the main data (users, auction etc) are stored in mysql.
To realize a real-time system I use node.js to develop a websocket (i used socket.io) where i catch bids data from redis. Making control with php if the user is logged is very simple of course but I want to make sure my system controlling if the request was made by a logged users also in nodejs. How can i do it? passing users data every socket request is not sure and this mean that every time I have to make a query to mysql to check if the user exists (not really a good practice) and this i think will slow my system. Do you have some idea?
You only need to authorize the user once after creating a new connection. Such an send authorization cookies after connection. After checking the cookies you can bind the current connection to the user. For greater security you can send in response to client a small random key dependent on ip addresses. This key will be sent with each request. You do not need to make an additional mysql request to check it out.
Almost everything is in the title :
Here's what I'd like to do :
A nice html page with a php authentication process (http first then https & so on)
Launch a flex app which knows (I don't know how (this is the actual question !)) the user has already been authenticated and display his/her stuff he/she has to do for the day (or whatever...).
Of course if someone try to call directly the flex app I would display an "authentication error" message and then redirect to the authentication page.
I'm sorry for my English which is perfectible.
I was thinking about the session cookie : first authenticate then ass a variable on the server side, something like :
$_SESSION['authenticate']=true
Then, on the flex side, just send the cookie and ask if the user is properly authenticated, something like calling a php web page like :
https://is_authenticated.php?php_session=xxxx
Thank you
Olivier
What are you using on the server side? Remember that you shouldn't do anything in the flex application other then send the SESSION ID along with any requests. Any time where the client checks security, you have a bug. The server must validate the session and determine if the request is allowed.
It sounded in your last comment that you are worried about people manually calling a web page. Each page must check to see if the user is authenticated. I don't know your specific application, but you may try looking at AMFPHP and see how they do session authentication. Good luck!
Your on the right track!
You could use session-authentication, these links might help you out:
http://www.zend.com/zend/spotlight/sessionauth7may.php
http://www.tizag.com/phpT/phpsessions.php
There is also the possibility to use http-authentication
http://se2.php.net/features.http-auth
however http-authentication is not as flexible as session-authentication, and also means some more configuration on the serverside.I would therefore recommend you to stick with sessions.
This is exactly what I would do.. A few things to consider from a security standpoint:
If your php service (from flex) gets an unknown session token, always generate a new one. This also applies to your PHP application and is often overlooked.
I would generate the swf with javascript, and manually insert the session cookie using javascript. This way people won't download and safe (or cache) your php pages with sessions that are invalid in the future.
Even better would be to use a separate token other than the session, and on the server figure out what the session id was based on this flex token.