
All browsers have an option that allows you to prohibit the receipt of cookies from third-party sites (for example, from an iframe with a domain other than the current one). In some browsers (hello, Apple) this feature is enabled by default, but often users turn it on independently and safely forget about it, as a result of which the developer cannot write the necessary data into cookies or localstorage. For example, when developing applications for VKontakte, you may encounter such a problem.
I want to share a simple and elegant solution how to get around this limitation.
In principle, when we have any other way to identify the user, this problem is not so acute, you can always write down or retrieve the necessary data from the database. But for small applications, this is an additional load, especially if you need to store a couple of lines.
')
Fortunately, the VKontakte API has
methods for storing data on the VK servers (key-value storage). We can only write and read data from there. But we will try to make it as beautiful as possible.
Suppose that we need to write some user data in cookies (for example,
we need to store a user authentication token on Instagram). The main idea is to record data both in the cookie and in the VKontakte storage, and then as quickly as possible.
var data = 'abcde';
In the example above, we redirected the user to some page where the recorded data is required (in our application, this is the main page that uses the received token). It is clear that the next time the application is loaded, this data will disappear from the GET – parameter and remain only in the VC repository. Of course, we can get them using the Javascript API, but we are writing an elegant solution ;-).
To be able to get our data on the server side of the application, we must fill in the “First API request” field in the application settings:

method=storage.get&key=userdata&format=json&v=3.0
Thus, VKontakte when accessing our application will be transmitted by the GET – parameter
api_result - there will be a JSON object with our cookie in it. Also, nothing prevents you from checking for cookies in nginx (if you change format to xml):
if ($arg_api_result ~ "%3Cresponse%3E(.*)%3C%2Fresponse%3E") { set $userdata $1; rewrite ^ /page_for_logined_users?userdata=$userdata? redirect; }
So, on the server side, we can do something like:
$userdata = (isset($_COOKIE['userdata'])) ? $_COOKIE['userdata'] : (isset($_GET['userdata'])) ? $_GET['userdata'] : false;
and get the data safe and sound. If without the proposed perversions with nginx, then it suffices to parse
api_result :
if (isset($_GET['api_result'])) { $data = json_decode($_GET['api_result'], 1); $userdata = (!empty($data['response'])) ? $data['response'] : false; }
PS Also, taking this opportunity, I offer you an interesting way to optimize the load using the above method. For example, in the application, we need a certain token, which we store in cookies or in the VK storage. However, the application itself is a static html file, in which the server language, for example, is needed only to insert this token into the application. Of course, we can request from JS the necessary cookie or data from the VKontakte store, but we are writing an elegant solution ;-).
So, you can configure nginx (or Apache) as follows:
Well, in Javascript get the necessary data:
var token = window.location.hash.substring(1);
In this way, we will be able to send all logged users to the html file (which nginx will return very quickly), passing any necessary parameters to the hash. And the file itself can generally be transferred to a CDN, thereby further reducing the load on your server.