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?
Related
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?
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]
I want to compare the key of a cookie with a key found in the database so as to let a returning visitor login to the site automatically,this means that the key in the db and the cookie will be associated with a specific user.
My question is what is better, storing the key to a table where the username is stored along
with their password, or create a separate table there will be the username with the associated key and timestamp of course.
Complexity is an issue here-furthermore I am trying to find a if innodb or Isam is better for the above.
What complicates the matter more is the fact that it is difficult to project from now
how big the application is going to be and how that might impact the design of the database.
The sooner I come to a sound solution the better
I am going to answer this with some thoughts and ideas on how to approach this.
Now what you should consider first when doing this is how other site do it:
Amazon allow you to browse the site under a persistent cookie however they do not allow the placing of orders or the changing of details without being forced to login again. However that being said this still has a serious security flaw. If you allow one click ordering and then some one else uses your computer and clicks on a link in a campaign email from Amazon (an Ad for example) there is still a chance that the order can be placed on the other guys account without having to actually be logged in (yep I found this out by accident, thankfully).
Facebook takes a similar approach to Amazon. From personal experience I think they demand a relogin every two days to edit account details etc.
Stackoverflow from what I can gather has no such security measures. Once you are logged in your logged in for a specified duration.
Google houses a 2+ year cookie and once every week or so asks you to re-login to validate yourself.
So as you can see many sites do not just allow persistent logins to control their user interactions and actually a returning persistent login rare even logs a person in fully. Instead what most sites implement is a 2 tier system of login where by you can view the site as the cookie user however you cannot edit anything without having to login again.
You will immediately notice once thing here. Many of these sites do not care for cookie expiration only for browser session expiration. Persistent cookies rarely have a short term expiration so this point is kind of useless. As #pyruva states it is easy to steal someones cookie and view a site as them, this happens on Facebook all the time (you can even find video tutorials on how to do it).
So the first thing to remember is that a persistent login, by nature, is insecure. The way to make it secure is normally within your application logic by implementing something such as a 2 tier authentication system.
The one thing you should never do is store some personally identifiable information about the user within that cookie such as the username or password, even in hashed form. A better way is to use a randomly generated token (think of OAuth2 here) to handshake with the server initially.
Of course one other thing you will need to consider is protecting your cookies in general. You can find a lot of resources on Google about this however here is one link that should help a lot: http://www.codinghorror.com/blog/2008/08/protecting-your-cookies-httponly.html
So hopefully that should give you some direction and hints on how to tackle this.
Edit
Every user that comes to your site has effectively two sessions when it comes to cookies. They have a browser session which, when the browser is closed, will delete the cookies from their browser (normally denoted as 0 expire time within HTTP headers).
Then there is the persistent session. The one you are tying to implement now, where cookies can last years before they actually expire.
This is what I mean by browser expiration. So most sites house temporary cookies which will be removed once you close the browser. These cookies are normally used to keep your session yours.
If sites cared about cookie expiration then they wouldn't house cookies which are valid for 2 years on your computer. Let's face it if some one is gonna use expired cookies to abuse your account they are kinda out of luck since the cookies are still perfectly valid. This is a greater security threat but it does prove my point.
I have an PHP Application. If I have logged in that application I am trying to pass the parameter as querystring through an iframe to the asp.net page.
Is there any other way to implement other than using an iframe?
Instead of having the PHP application submit data to your ASP application, it would be better if they could natively and securely share some of the data.
How?
Well, your goal is having one script tell the other that the user has been logged in, right? In PHP, this is usually done by putting something in the $_SESSION. Your ASP application can't read $_SESSION, though. You'll need to use something else.
When the user logs in, create a unique value. Maybe the result of hash_hmac over some interesting data? Whatever it is, it should be unique every time it's created and unguessable. Don't throw in things like the user's IP address or the current time.
Save the unique value to a database table that both applications can read. Also store other information that will help identify the user, such as her identifier (user_id or whatever you have on hand).
So, the PHP code that logs the user in has created this unique value and stuck it in a shared database table. Now, the PHP application should forward the user to your ASP application. Include the unique value in the request.
When the ASP application receives the request, it will look for the unique value. If it's found, it can look in the shared table. If the value is found in the table, it can then take whatever measures it needs to in order to mark the user as logged in.
Once the ASP application has logged the user in, then it should delete the unique value from the shared table. The user can be forwarded to wherever she was going in the first place.
By making the key usable only one time, and only after a successful login in the PHP application, you'll reduce the possibilities of abuse by malicious or curious users. All of the important information will be hidden in the shared database table.
Be warned that this is an overly simplistic implementation of "single sign on" and is full of caveats and edge cases. While it might work for you, it might not be the best solution. Given your question history, it looks like you've been struggling with similar issues for quite some time. You might want to give some thought into using a slightly more "industry standard" SSO mechanism. SAML is the 800 pound gorilla of SSO standards. I normally wouldn't wish it on my worst enemy, but maybe it's the thing you're really looking for here.
Also, don't use iframes, they're cookie eating disasters in some browsers.
This is a beginner question...
In a website, what type of data should or should not be included inside the session? I understand that I should not include any info that needs to remain secure. I'm more interested in programming best practice. For example, it is possible to include into the session some data which would otherwise be sent from page to page as dependency injection. Wouldn't that correspond to creating a global variable?
Generally speaking, what kind of data has or hasn't its place inside a session table?
Thanks,
JDelage
The minimum amount of information needed to maintain needed state information between requests.
You should treat your session as a write-once, read many storage. But one which is rather volatile - e.g. the state of your underlying application data should be consistent (or recoverable) if all the sessions suddenly disappeared.
There are some exceptions to this (normally the shopping basket would be stored in the session - but you might want to perform stock adjustments to 'reserve' items prior to checkout). Here items may be added/edited/changed multiple times - so its not really write-once - but by pre-reserving stock items you are maintaining the recoverabiltiy of the database - but an implication of this is that you should reverse the stock adjustments when the session expires in the absence of completion.
If you start trying to store information about the data relating to individual page turns, you're quickly going to get into problems when the user starts clicking on the forward/back buttons or opens a new window.
In general you can put anything you like in a session. It's bad practice to put information in a session that has to be present to make your page run without (technical) errors.
I suggest to minimize the amount of data in your session as much as possible.
stuff you can save in the session so that you dont have to make another database query for info that isn't going to change. like their username, address, phone number, account balance, security permissions on your site, etc.
(This is perhaps more than you're looking for, but might make for good additional information to add to the good answers already posted.)
Since you mention best practices, you may want to look into some projects/technologies which can be used to take the idea of session state a bit further. One common pitfall with horizontally scaling web applications across multiple servers is maintaining session state between them. (User A logs in to Server A which stores the user's session, but on the next request hits Server B which doesn't know about User A's session, etc.)
One of the things I always end up saying to myself and to colleagues is that session by itself isn't really the best place to store data, even if that data is highly transient in nature. A web server is a request/response system, not a data store. It's highly tuned to the former, but not always so great for the latter.
Thus, there are ways to externalize your application's session data (or any stateful data, which should really be kept to a design minimum in the RESTful stateless nature of the web) from your web server and to another system. Memcached is a very common tool for this. There are also drop-in session replacements (or configurable session options for various frameworks/environments) which store session in a database like SQL or MySQL.
One idea I've been toying with lately is to store session data (well, any transient data where it's OK to lose it in a catastrophe) in a NoSQL database. CouchDB and MongoDB are my current top choices for this, but there's no shortage of other options. CouchDB has excellent horizontal scaling, MongoDB is ridiculously fast when run entirely in-memory, etc.
One of the major benefits of something like this, at least for me, is that deployments can easily become non-events. The web services on any given server can be re-started and the applications therein re-initialized without losing stateful data. If the data is persisted to the disk (that is, not entirely run in-memory) then the server can even be rebooted without losing it. Servers/services can drop in and out of the farm and users would never know the difference.
Additionally, externalizing this data allows you to analyze the data in potentially useful ways. Query it, run metrics on it, interface with it via other web applications or entirely offline tools, etc. It really opens up the options as a project grows in complexity.
(Again, this isn't really intended to answer your question, but rather to just add information that you may find useful. It's something my colleagues and I have been tinkering with as of late and your question seemed like a good place to mention it.)