Session management by sending
cookies on websites has become so common that without this, probably, no project requiring user authorization can do without it. It would seem that the mechanism is so studied that problems with it are simply unthinkable.
We also thought so when developing an iframe application for VKontakte.
But after the application was developed (the development was conducted mainly in Mozilla Firefox and Google Chrome), it turned out that it was not working in Internet Explorer, which later was joined by the latest versions of Opera and Safari.
Under the cat a detailed description of the problem and its solutions.
Description of the problem
First of all, it was established that
cookies are successfully transmitted by the server and received by the browser, but that, in turn, does not save them and does not send them back to the server along with the following requests.
')
The behavior seemed strange, but it has an objective rationale: the browser provides privacy for browsing pages and does not accept
cookies from pages inside the
iframe .
I will give an example.
Suppose you pick up a laptop and read web pages with benchmarks and various laptop comparisons. On some of these pages, for sure, Google AdSense or some other similar system will be installed, which has the ability to send you a unique value through
cookies and further identify you by it. Later, reading the news, documentation on your favorite framework or participating in discussions on forums, you will be surprised that in advertising you are shown offers to buy laptops. And, in the meantime, the advertising system will increase the CTR for someone. ;)
Browsers are trying to protect us from this kind of information gathering and prohibit the receipt of
cookies from the pages inside the
iframe .
But we have nothing to do with advertising and collecting information, so we will consider solutions to the problem.
Cookie in iframe and Internet Explorer
In our case, the solution for Internet Explorer was not long in coming: the problem was considered many times and the answers were quickly found in Google.
The solution is to send an HTTP header with the following content:
P3P: CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"
In particular, for PHP it will look like this:
<?php header('P3P: CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');
Cookie in iframe and Opera / Safari
The problem in these browsers appeared not so long ago, and therefore it turned out to be a bit more difficult to identify and solve.
The essence of the problem is that in the latest versions of these browsers, the default checkbox is
"Cookies: Accept only from the visited site" (Opera) and
"Accept cookies: Only from the visited sites" (Safari)
The obvious solution is to change the cookie reception mode to “always”. However, in most cases it is not possible to “ask” all users to do this.
Therefore, we will try to consider other ways to solve the problem.
Method 1. Splash Screen instead of the first page
A more detailed consideration of the problem showed that
cookies are not set before any user actions. After the user goes to another page in the
iframe , clicking on a link, the
cookies begin to be successfully accepted.
It is worth paying attention to the fact that emulation of switching to another page
does not help. Namely:
- redirect with the HTTP Location header
- redirect with the appropriate meta-tag
- Redirect with a window.location change from JavaSctipt
- redirect using a link () method from JavaScript
The obvious solution: instead of the actual site, the first page should display a greeting with the link “go to application”.
Advantages:+ simplicity, bulletproof
+ independence from having javascript enabled in the browser
Disadvantages:- requires additional action from the user
- inconspicuousness (an extra page with an “incomprehensible” greeting)
Method 2. Redirect using form submission
In the methods of transition emulation I have listed, it is not without reason that there is no redirect by sending a form.
The essence of the method:
- in the iframe creates a form, the action of which leads to the desired page of the current domain
- form is submitted via javascript
And this method works: the script located at the address of the form's action (and subsequent scripts to be called) will successfully set
cookies .
It doesn’t matter whether the form is sent by GET or POST.
An example implementation using jQuery:
<script type="text/javascript"> $(function(){ $('body').append('<form id="cookiesHackForm" action="http://example.com/" method="get"></form>'); $('#cookiesHackForm').submit(); }); </script>
Advantages:+ does not require user action
Disadvantages:- JavaScript required
- requires a blank page only for redirect
Method 3. Sending the form in the background using an additional iframe
It is a development of the second way in which the lack of a redirect is eliminated.
In order to avoid having an extra blank page for the redirect, we can create an additional
iframe to which we will send the form described above. Thus, we will show the user some useful page, and set
cookies "in the background."
An example implementation using jQuery:
<script type="text/javascript"> $(function(){ $('body').append('<iframe id="cookiesHackFrame" name="cookiesHackFrame" src="http://example.com/blank.html" style="display:none;"></iframe>'); $('body').append('<form id="cookiesHackForm" action="http://example.com/" method="post" target="cookiesHackFrame" >'); $('#cookiesHackForm').submit(); }); </script>
Advantages:+ does not require user action
+ no redirect required
Disadvantages:- JavaScript required
- it does not make sense where the page should be displayed only after the installation of cookies
Conclusion
Browsers care about our privacy, but the presence of workarounds makes you wonder whether these paths are a bug or a feature. In the first case, some time after the corresponding patches, you will have to abandon solving problems in such ways. But, while they work, there is no reason for not using them.
Related Links
http://www.w3.org/TR/P3P/#guiding_principleshttp://stackoverflow.com/questions/389456/cookie-blocked-not-saved-in-iframe-in-internet-explorerhttp://stackoverflow.com/questions/2691864/facebook-iframe-app-with-multiple-pages-in-safari-session-variables-not-persistinhttp://developers.facebook.com/docs/best-practices#miscellaneous-issueshttp://anantgarg.com/2010/02/18/cross-domain-cookies-in-safari/http://lightyearsoftware.com/2009/11/on-the-pain-of-developing-for-facebook/http://javascript.ru/unsorted/id (thx
seriyPS )
UPD: if someone prompts a more suitable blog, I will be very grateful.
UPD2: moved to the Blog Browsers for recommendations. (thx
agul )