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.
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
The scenario is this:
An iPhone app connects to a WebServer with Appache, PHP & MySQL.
The iPhone app has a timeout of 5 seconds on connections(Async NSURLConnection). IF the response from server comes after the timeout the application doesn't know and tries to send the data again.
On the server the php script runs twice. Once when the first set of data arrived. It creates a new user in the database but by the time it should echo the response the app timeouts. The second time the app tries to create the user it receives an error because the username should be unique. This happens because the first time the php script already inserted the user into the database.
In this case the user is created on the server but the user doesn't know this because he receives an error with user already created.
A few things:
- The timeout can be increased but it doesn't matter. The server can take even more to create the user when under load.
- I can test if the user can login and instead of trying to create I just login him normally. The problem here is what happens if two users try to create a user with the same username and password because in that case the second user will automatically login. In this case I can indeed add a check to see if the user was created in the last minute and just login if so. (The thing is if the script takes more than 1 minute to execute the server should crash first, the create user script takes 0.001 seconds to execute and under load it takes 3-4).
Is there any way to prevent a php script from executing if another one is executing with the same data? Or is there another solution to this problem?
I am not sure about the php route but one solution from the iPhone side is to include in your client's http request a vendor specific device identifier from UIDevice's identifierForVendor: This way you can identify whether the create request is coming from the same device (same iPhone user) or someone else. If this unique id does not match up, you can give your "Sorry, this username is taken" message.
As a side note though, if the users create a user with the same username and password then it is usually valid to assume it is the same user trying to log in on multiple devices (iPhone and iPad for example). This may be a use case that you want to support. The chance of two users independently trying to create the same user/password account is highly unlikely. It is less likely a scenario than the common scenario of someone randomly guessing a username/password combo and gaining access through that route. If you are using a username/password system the underlying assumption is that this represents an acceptable level of risk. Some strategies for minimizing this risk is to use password complexity rules, enforcing usernames to be valid and confirmed email addresses, and in extreme cases to use two factor(or more) authentication.
There is a device ID present in all iphones and they are all unique, verify on your language how are you going to get that once a user tried to register using their iphone. so using that device ID they cannot make registration more than one.
First choice is probably assume that they are the same user (or ought to pick better passwords) and let them in, as #Aaron says.
Two other possibilities, depending on how much duplicate users matters:
1) Use an email address and have them verify their user-create action. If you get a duplicate register request you can just put up a the same "see your email, click here to resend" screen.
2) Use database transactions to ensure that only one connection can login / register at the same time. Horrible scalability.
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 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.
I have a basic knowledge of websockets and I've set a web socket sever up on my VPS host.
I have a user system with database. I was planning on having a table called 'chat_log' too.
I want to use my web socket sever on different pages.
Say for example on each user's profile there was a chat.
I'd have a column in the database of to where the chat was posted to. Then it would run a query to check where the chat was posted to, if it was posted there display it.
Could I achieve the same effect (combining PHP database techniques) with web sockets to create a chat based on database results?
Also another thing, how could I send where the chat was posted to? If it's not sent? Is there a way of getting the GET variable from the URL in javascript and sending that DATA separately, so it can be processed in the php?
Can't you pass the $_GET variable to javascript which then pass it to your websocket server? Assuming your websocket server has a database connection.