# Проброска cookie

В сентябре 2019 года компания Apple представила ITP 2.3, который принудительно удаляет 3rd-party cookie через 7 дней. Google также ограничивает использование 3rd-party cookie и анонсировал блокировку их использования по умолчанию в будущих обновлениях браузера. С 2019 года Mozilla блокирует 3rd-party cookie по умолчанию. 🛡️ Скорее всего, другие браузеры либо уже внедрили, либо планируют ввести подобные ограничения.

---

## 🚨 Как это влияет на вас?

Если пользователь Safari не посещал ваш сайт более 7 дней, **cookie с идентификатором SLID будет удалена**. Это означает, что пользователь будет распознан как новый, что может:

- Завысить количество пользователей Safari в аналитике.
- Повлиять на персонализацию, отчеты и A/B-тесты.

**Решение:** передавать SLID-cookie через сервер, делая её **1st-party**. Это позволяет избежать ограничений браузеров. 🎉

!!!
Данные ограничения работают аналогичным образом в любом браузере, ограничивающим 3rd-party cookies. В будущем, в процессе разработки могут появиться различия в деталях реализации ограничений.
!!!

---

## Как передавать SLID cookie со своего сервера?

Решение заключается в настройке вашего бэкенд-приложения для установки SLID-cookie на домене сайта. Это делает cookie **1st-party** и позволяет ей избежать удаления. 

### Основные шаги:

1. **Проверить наличие cookie у пользователя.**
2. **Обработать cookie по одному из сценариев:**

    - Если у пользователя есть cookie `_slid_server`, обновить срок её жизни до одного года. Значение идентификатора остаётся неизменным.
    - Если у пользователя есть только `_slid`, скопировать её значение в новую cookie `_slid_server`. 

=== Пример
Допустим, значение `_slid` — `63317316ce625bd9270b6442`.  
Необходимо продублировать его в `_slid_server` и установить срок жизни в *31556951 секунд*.  

**Результат:**  
`_slid_server=63317316ce625bd9270b6442;max-age=31556951`
===

!!!warning
Устанавливайте cookie с корневого домена, например, `.yourdomain.ru`.
!!!

!!!warning
Cookie не должна содержать атрибут `HttpOnly`.
!!!

### Сценарий взаимодействия

1. Пользователь заходит на ваш сайт.  
2. Ваш сервер (бэкенд-приложение) проверяет запрос:  
   - Есть ли `_slid` cookie?  
   - Есть ли `_slid_server` cookie?  
3. Если `_slid_server` отсутствует, создаёт новую cookie `_slid_server` с тем же значением, что и `_slid`.  
4. Новая cookie возвращается в заголовке ответа с максимальным сроком жизни 1 год.  
5. При последующих визитах пользователи продолжают получать персонализированный контент без потери данных.

![slid.drawio.png](../../images/cookie_front_end/slid.drawio.png)

---

## Примеры кода 

Примеры кода для настройки SLID cookie на разных языках программирования.

+++ cURL
```jsx
    >>> curl -v http://yoursite.example.com --cookie "_slid=63317316ce625bd9270b6442"                                                                                                                                                                                                                     
    *   Trying 172.217.18.4...
    * TCP_NODELAY set
    * Connected to yoursite.example.com (172.217.18.4) port 80 (#0)
    > GET / HTTP/1.1
    > Host: yoursite.example.com
    > User-Agent: curl/7.64.1
    > Accept: */*
    > Cookie: _slid=63317316ce625bd9270b6442
    >
    < HTTP/1.1 200 OK
    < Date: Mon, 30 Mar 2020 16:55:16 GMT
    ...
    < Content-Type: text/html; charset=ISO-8859-1
    ...
    < Set-Cookie: _slid_server=63317316ce625bd9270b6442; expires=Wed, 29-Apr-2021 16:55:16 GMT; path=/; domain=.google.com; Secure
```
+++ NodeJS c использованием Express и CookieParser 
```jsx
    // need cookieParser middleware before we can do anything with cookies
    app.use(express.cookieParser());
     
    app.use((req, res, next) => {
      if (req.cookies._slid) { // проверка, если пользователь вернувшийся и SLID кука уже есть
        const slid = req.cookies._slid;
        res.cookie('_slid_server', slid, { // сохраняет новую серверную куку с именем "_slid_server" со значение SLID
          expires: new Date(Date.now() + 31540000000000), // устанавливает срок жизни новой куки в 1 год
        });
      }
      next();
    });
});
```
+++ Python (Django)
```jsx
    ...
    slid_cookie = request.COOKIES.get('_slid') 
    if slid_cookie is not None: # проверка, если пользователь вернувшийся и уже имеет SLID куку
        set_cookie(‘_slid_server’, slid_cookie, 31540000000000) # сохраняет новую серверную куку с именем "_slid_server" со значение SLID
    ...
```
+++ PHP
```jsx
    <?php
    if(isset($_COOKIE['_slid'])) {
     $slid_cookie = $_COOKIE['_slid']; /* проверка, если пользователь - вернувшийся и SLID кука уже существует */
     setcookie('_slid_server', $slid_cookie, time() + 31540000000000); /* срок жизни 1 год */
    }
    ...
```
+++

---

## Проверка установки cookie в Chrome

Для проверки:

1. Откройте инструменты разработчика (`Ctrl+Shift+J` / `Cmd+Option+J`).
2. Перейдите во вкладку **Network**.
3. Включите опцию **Preserve Log** и обновите страницу.
4. Найдите запрос к вашему сайту.
5. Перейдите в **Headers** -> **Request Headers**. Убедитесь, что значения `_slid` и `_slid_server` совпадают.

![Пример настройки](../../images/cookie_front_end/Screenshot_17.png)

!!! Примечание
Обратите внимание, что проверка корректности кук **невозможна** через раздел Applications инструментов разработчика, так как в этом разделе включены как куки серверной, так и клиентской стороны и некоторые из них могут быть автоматически удалены Safari.
!!!
