Cookie vs MySQL Save - php

I guess this is more of just a personal preference questions, but I'm really concerned with performance. I'm working on a little project and one thing that people can do is RSVP to events. Now I know the option that people choose (attend or not attend) must be stored in a database, but to make the site look a little better, I also want the button that allows someone to attend switch to not attend when they click it.
At this point I'm thinking of three options, either query the database, figure out if the person is attending, and display the appropriate button. -OR- I could save the information in a cookie and just pray that the user doesn't delete the information. -OR- I could save the information in a cookie, if the cookie is present then display whatever the cookies says, if not then query the database. Option 3 seems the best to me.
I always kind of inspect major sites and look at some of the techniques they use. They tend to keep the cookie count under 20. Is there anything bad about option 3, or is it the way I should go. Thanks!

If you use cookie, you can expect that there is some other person who uses the same machine, the same user account, the same browser, the same settings. There can be also a person who uses different browsers. There can be also two persons who share two computers.
If the users log in you can use sessions, it is cookie, of course, but you can identify the user, so he knows "it's not me".
And about performance: if you set your cookie, it takes also time to get it and then send it, via http headers and responses. But the best idea would be to benchmark this. Because of the small time to access db and for the reasons I stated before, I would use the db.

Store it in the db. If the user logs in on a 2nd machine and changes the status, the wrong status will show when they go back to the 1st machine.

Without the details on how people access the site, whether they are logged in or not, it is hard to say but I would agree with you on the 3rd option - query the cookie first if there i nothing, query the database - which works as long as no two people use the same computer session.
Another option that may work (or not depending on your web app) is to have individualized links. This can work nicely if people come to your site from email links with a url similar to this http://example.com/[eventid]/[uniquecode]

Related

How to handle sessions in backend across different devices?

I have looked through this Question, but I really didn't get an answer for what is the standard for handling sessions if I am storing them in a "MySql table". What should actually be stored into a session row, so that I can distinctly identify sessions from different devices. I read the answer saying persisting a login from the client side, that can be done.
But:
I don't want to logout all the devices when there's a logout action from one of them, this means I would really have to store different active sessions for the same account.
What can be the item which I can actually stored in the backend to distinguish the devices. I don't prefer storing the IPAddress and also there is browser fingerprinting, even they are not 100%.
You can give me suggestions on how to handle them in different rows or how actually should this be handled. And If you are suggesting not to use MySql for this, can you be please more elaborate?

How to recognize 2 PCs with same IP and browser(version)

I want to give a "like" option on my page for non-logged users.
The simpliest thing would be to detect user IP ( e.g. by $_SERVER['REMOTE_ADDR']).
More sophisticated would be detecting user's agent (e.g. by $_SERVER['HTTP_USER_AGENT']).
But I want to give like-posibility for "each PC in family" (real-life family) - this could also mean they all have not only the same IP, not only the same browser but also the same browser-version...
So how would I determinate whether it is a different PC? (without using cookies/session)
I want to store one "like" per PC and since cookies can be cleared I didn't want to use them :)
I wanted to abstract my particular interest from the whole problematics - so I did.
However you should never trust user input (as David pointed out) - so do not base your final like-count on just that ! At least put a likes/per IP limit and combine it with cookies/session.
Your only option to do this outside the simple methods of using cookies, logins, etc. is to do browser fingerprinting. This technique involves gather a variety of information that the browser outputs to the server/webpage and making a hash of it to create a unique ID for that client. It has a remarkably high accuracy and would work fairly well under the circumstances you are describing.
It is based on the idea that "no two browsers are exactly the same". In other words, you look at screen resolution, user agent strings, active plugins, etc. and create a "fingerprint" of those settings. There is almost always going to be a variance in some way.
There are available libraries that can help get you started. Here is one that is very easy to implement and understand... https://github.com/Valve/fingerprintjs
You can use sessions without using cookies. When the user logs in, they get a token, and this token is appended to every URL they visit. (In PHP you can see this if you disable cookies in the browser, you will get "PHPSESSIONID" in the URL). So, if you make users log in before voting / liking / whatever, then you can achieve this using sessions but not cookies.
If you are talking about public users without a login mechanism, then there really isn't any way to achieve this, unless you set a cookie recording the fact that this browser has voted.
Note however that not only can cookies be deleted, but it won't actually achieve what you want unless everyone in the family uses a different browser or has a separate login on their operating system. Otherwise they are effectively all the same user as far as you can tell. Also people can use multiple browsers so one person could vote / like more than once anyway.
Detecting the User Agent can easily be spoofed; so it isnt a reliable way. The best way to do this is sessions or cookies. Why do you not wish to use them?
Short answer: you can't.
Remember, each request to a web server is a new event. Cookies are the only way to persist data between calls. So if you rule them out you really can't differentiate them. This is a major reason why Google puts long life cookies on their site.
Can cookies be deleted? Sure. But they're really the only option you have.
You cannot give a single identity to a PC.
Cookies can be cleared.
User logins can be done from different computers.
$ip.$http_user_agent will not work.
User may restart the modem and ISP might assign a new IP.
Or use a different browser to change $http_user_agent.
Or another system on a LAN might have the same $http_user_agent.
What is the significance of giving one "like" per PC (provided you are able to even identify a PC correctly)?
What if two different users with different tastes use the same PC?

Ajax/Php - Real Time Online User Counter

I want to have an Online user counter but something which performs real time. I mean when someone comes in, the counter updates, or when someone leaves the site, the counter decrease.
I can't find anything like this on net. Is there any script for this ?
You could probably keep a list of all sessions in a database and update the "online time" every time someone hits a page. Then check how many sessions were updated in the last x minutes. However, this won't be very real time: depending on the amount of minutes you defined it will be a little bit off.
Even Google Analytics (the new real time version) gets it wrong sometimes. Don't worry too much if you can't get it right either. ;-)
You should have a look to WebSocket. There is a lot of demos out there, mostly real-time chat application, you could hack something on it :)
In my opinion, WebSocket seems a bit overhead in you case (you just want a number, no real two-sides communications) but it's the good way to do "real-time" apps.
Here are some links:
Socket.IO (node.js backend)
WebSocket and Socket.IO
Introduction to Server-Sent Events (another technique)
phpwebsocket
as far as i know there is no way to track when a user leaves your site, short of a log out button (which one can easily avoid by simply closing the window)
To expand on Tom's answer, you could create a table that tracks sessions in a database. At minimum the fields should be session_id, ip_address, activity_time. Name them whatever you'd like. You would need a function that executes on every page load that matches a record on session_id and ip_address. If a matching record does not exist, you create one; if a match is made, then update the time.
A few caveats:
1) getting the right ip address can be tricky, especially with AOL users and/or proxy users. You need to look for X_Forwarded_For headers. If they exist, for a user, use that address, otherwise use $_SERVER['REMOTE_ADDR']. I would suggest looking up X_Forwarded_For for your setup because Im not sure its available for all setups
1a) if you dont get the right ip address, some users will create a new entry on every page view
2) You need a way to remove stale sessions. I suggest as part of the function that updates the activity time, it also checks for any activity_time that is older than 5 minutes (I use 15 minutes) and if so, removes the corresponding record.
Then all you need to do is a simple count on the table and that will give you a reasonably accurate representation of the number of users currently online. With very little coding you could put this to a lot of uses. On a dating site I created I added an extra column to the table and was able to display an online icon next to users that were logged in, the same in search results to show users doing searches what users were currently online. with a bit of imagination it could be used for a few more scenarios.
Also, with a membership feature, when a user logs in you can update the session table to show that they are a member rather than a guest and if the user logs out you can remove the session from the table. Its best when a user logs out but stays on the site that you generate them a new session for security purposes. This is a bit more than what you were asking for.
You have the browser leave an HTTP connection open to your server for some unused resource (like /usercounter) that your server never responds to. Then you count the number of open connections. You can have the request send a cookie associated with the user's session so you can know if the connections are all unique users. This solution is very difficult and you will likely not find any ready-to-go solutions for implementing this.
The solution above will get a count of users who have javascript enabled. For other users, you would have to have some sort of guesstimate of how long a user would be around and update that timer on each page load.

Best method to prevent gaming with anonymous voting

I am about to write a voting method for my site. I want a method to stop people voting for the same thing twice. So far my thoughts have been:
Drop a cookie once the vote is complete (susceptible to multi browser gaming)
Log IP address per vote (this will fail in proxy / corporate environments)
Force logins
My site is not account based as such, although it aggregates Twitter data, so there is scope for using Twitter OAuth as a means of identification.
What existing systems exist and how do they do this?
The best thing would be to disallow anonymous voting. If the user is forced to log in you can save the userid with each vote and make sure that he/she only votes once.
The cookie approach is very fragile since cookies can be deleted easily. The IP address approach has the shortcoming you yourself describe.
One step towards a user auth system but not all of the complications:
Get the user to enter their email address and confirm their vote, you would not eradicate gaming but you would make it harder for gamers to register another email address and then vote etc.
Might be worth the extra step.
Let us know what you end up going for.
If you want to go with cookies after all, use an evercookie.
evercookie is a javascript API available that produces
extremely persistent cookies in a browser. Its goal
is to identify a client even after they've removed standard
cookies, Flash cookies (Local Shared Objects or LSOs), and
others.
evercookie accomplishes this by storing the cookie data in
several types of storage mechanisms that are available on
the local browser. Additionally, if evercookie has found the
user has removed any of the types of cookies in question, it
recreates them using each mechanism available.
Multi-browser cheating won't be affected, of course.
What type of gaming do you want to protect yourself against? Someone creating a couple of bots and bombing you with thousands (millions) of requests? Or someone with no better things to do and try to make 10-20 votes?
Yes, I know: both - but which one is your main concern in here?
Using CAPTCHA together with email based voting (send a link to the email to validate the vote) might work well against bots. But a human can more or less easily exploit the email system (as I comment in one answer and post here again)
I own a custom domain and I can have any email I want within it.
Another example: if your email is
myuser*#gmail.com*, you could use
"myuser+1#gmail.com"
myuser+2#gmail.com, etc (the plus sign and the text after
it are ignored and it is delivered
to your account). You can also include
dots in your username (my.user#gmail.com). (This only
works on gmail addresses!)
To protect against humans, I don't know ever-cookie but it might be a good choice. Using OAuth integrated with twitter, FB and other networks might also work well.
Also, remember: requiring emails for someone to vote will scare many people off! You will get many less votes!
Another option is to limit the number of votes your system accepts from each ip per minute (or hour or anything else). To protect against distributed attacks, limit the total number of votes your system accepts within a timeframe.
Different approach, just to provide an alternative:
Assuming most people know how to behave or just can't be bothered to misbehave, just retroactively clean the votes. This would also keep voting unobtrusive for the voters.
So, set cookies, log every vote and afterwards (or on a time interval?) go through the results and remove duplicates based on the cookie values, IP/UserAgent combinations etc.
I'd assume that not actively blocking multiple votes from same person keeps the usage of highly technical circumvention methods to a minimum and the results are easy to clean.
As a down side, you can't probably show the actual vote counts live on the user interface, or eyebrows will be raised when bunch of votes just happen to go missing.
Although I probably wouldn't do this myself, but look at these cookies, they are pretty hard to get rid of:
http://samy.pl/evercookie/
A different way that I had to approach this problem and fight voting fraud, was to require an email address, then a person could still vote, but the votes wouldn't count until they clicked on a link in the email. This was easier than full on registration, but was still very effective in eliminating most of the fraudulent votes.
If you don't want force users to log, consider this evercookie, but force java script to enable logging!
This evercookie is trivial to block because it is java script based. The attacker would not likely use browser, with curl he could generate tousends of requests. Hovewer such tools have usually poor javascript support.
Mail is even easier to cheat. When you run your own server, you can accept all email addresses, so you will have practically unlimited pool of addresses to use.

Ways to determine returning "anonymous" guests in PHP

Two types of users visit my website: registered users and guests. Registered users are tracked and retained by PHP session, cookies and individual logins. Guests I find trickier to manage so I give little to no authority to contribute content.
I want to open up editing for users (registered or not) to save favourites, shopping carts, vote in polls, moderate, tag, upload and comment. At the same time, protect the data from other non-registered users.
What are some options or best practices to determine a unique visitor from another and some security measures to consider when allowing them to contribute more? Should I work around their security/restriction settings to provide contribution service or should I expect them to meet in the middle and relax some of their settings to allow cookies etc?
IP Address - The IP is an option but only temporary. It can change for a user reconnecting to their Internet with a different IP, and for that matter another user may eventually share the same IP. IP can also be anonymous, shared or misleading.
PHP Sessions - OK for a session (and if enabled) but lost on closing the browser.
Cookies - Can store session data but is easily (and often) disabled from the client-side.
Header data - combining known details of he user might at least group users - ISP, browser, operating system, referring website etc.
Edit: I'm still having trouble getting my head around all the the key factors involved... we set up a cookie for a guest. Attach a bunch of edits and user history to that session. If the cookie is removed, the data floats around attached to nothing and the user loses their data. Or if the user logs in, the guest and user data should be merged...
I think cookies would probably be the best option here as it's the only way you are going to be 100% sure requests are unique. Of course, you could possibly add a mix: if cookies are disabled you might be able to try other options of identification such as the IP address method, but that could make it overly-complex.
As you say, IP address is liable to change and in some organizations there may be a group of proxy servers setup which make requests originate from different IPs. Of course, you could check X_FORWARDED_FOR, but they are still liable to change.
Header data is probably going to prove difficult to get good results on I think. If you've got an organization that has the same browser, OS, IP it is going to show people as being the same. Even people not in the same organization may still appear similar (i.e AOL users who get their traffic usually routed through proxy servers, the majority will probably be using the 'AOL browser' that gets shipped with it giving similar headers).
Out of those two options, the IP one is going to be easy to implement but obviously there are the problems I outlined. Checking for unique data in the headers will prove to be absolute pain I think.
Obviously as you say, sessions are lost on closing the browser, and it appears you want the system to behave as if they were a registered user so cookies seem a more obvious choice (especially as you want the 'favourites' to be persistent).
I would just go with sessions.
Your users could change IP addresses (prone to mixup behind NATs and proxies), modify/delete cookies (certainly possible), or change their header (easily through switching browsers).
There is no secure way of identifying a guest if they do not want to be identified. Just go with the standard: cookies/sessions.
You should use sessions.
Sessions id are stored in a cookie (or for users who doesn't accept cookie, stored in the url with the PHPSID argument)
They won't be erased when the user will close his browser, it just depends on how you set your session/cookies options.
You can set up the timelife of a session to whatever you want, so don't bother with this.
You should also tell to your user about this (enable cookie)
Concerning the data which could be merged when log in, it's your job, to merge it in a proper way, or even ask the user if the option should be saved or not.
You could use a combination of all of the identifying points that you can find, that are not likely to change, and are likely to be unique - looking at panopticlick you can gather a bunch of data such as installed fonts and browser plugins. You could take those kinds of more unique data points and hash them to give you an id, and then compare it against the less unique data like useragents and ip addresses.
But honestly, that's super complicated and sneaky. Use cookies/session. If the user doesn't want to enable cookies then they don't want all your anonymous tracking for a reason, and you should honor their decision.

Categories