HTTP cookie
HTTP cookie — это небольшой фрагмент данных, отправляемый сервером браузеру пользователя, который тот должен сохранить и отсылать обратно с каждым новым запросом этому серверу. Это, в частности, позволяет узнать, с одного ли браузера пришли оба запроса (например, для аутентификации пользователя). Они запоминают информацию о состоянии для протокола HTTP, который сам по себе этого делать не умеет.
Cookie используются, главным образом, для:
- Управления сеансом (логины, корзины для интернет-магазинов)
- Персонализации (пользовательские предпочтения)
- Мониторинга (отслеживания поведения пользователя)
До недавнего времени cookie принято было использовать в качестве хранилища информации на стороне пользователя. Но из-за того, что cookie пересылаются с каждым запросом, они могут сильно снижать производительность (особенно в мобильных устройствах). Теперь качестве хранилищ данных на стороне пользователя вместо них можно использовать localStorage, sessionStorage и IndexedDB.
Создание cookie
Получив HTTP-запрос, вместе с ответом сервер может отправить заголовок Set-Cookie . Cookie запоминаются браузером и посылаются серверу с каждым новым запросом. Можно задать срок действия cookie, то есть срок его жизни, после которого cookie не будет отправляться. Также можно указать ограничения на путь и домен, то есть указать, где cookie будет действовать — по какому пути и на каком домене. Например, cookie будут действительны для пути www.server.com/private или для домена private.server.com .
Заголовки Set-Cookie и Cookie
Заголовок Set-Cookie используется для отправки cookie с сервера на клиентское приложение (браузер). Этот заголовок с сервера дает клиенту указание сохранить cookie.
HTTP/1.1 200 OK Date: Sun, 07 Oct 2018 13:31:17 GMT Server: Apache/2.4.34 (Win64) mod_fcgid/2.3.9 X-Powered-By: PHP/7.1.10 Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate Pragma: no-cache Set-Cookie: PHPSESSID=m2iut9i59p73ld1c5q9j49c6t0; path=/ Set-Cookie: visitor=0d3749f09d222bea3b8f163937eb9bf1; Max-Age=31536000; path=/ Set-Cookie: lastvisit=1538919655; path=/ Vary: Accept-Encoding Content-Encoding: gzip Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Transfer-Encoding: chunked Content-Type: text/html; charset=utf-8 .
Теперь, с каждым новым запросом к серверу, при помощи заголовка Cookie браузер будет возвращать серверу все сохраненные ранее cookies:
GET /catalog HTTP/1.1 Host: www.server.com User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Referer: http://www.server.com/ Cookie: PHPSESSID=m2iut9i59p73ld1c5q9j49c6t0; visitor=0d3749f09d222bea3b8f163937eb9bf1; lastvisit=1538919655 Connection: keep-alive Upgrade-Insecure-Requests: 1
Сессионные, постоянные и безопасные cookie
Сессионные cookie, установка которых выглядит так:
Set-Cookie: lastvisit=1538919655
удаляются при закрытии окна браузера, то есть существуют только на протяжении текущего сеанса, поскольку атрибуты Expires или Max-Age для них не задаются.
Постоянные cookie удаляются не с закрытием клиента, а при наступлении определенной даты (атрибут Expires ) или после определенного интервала времени (атрибут Max-Age ):
Set-Cookie: visitor=0d3749f09d222bea3b8f163937eb9bf1; Max-Age=31536000
Set-Cookie: visitor=0d3749f09d222bea3b8f163937eb9bf1; expires=Mon, 07-Oct-2019 13:44:02 GMT
Безопасные cookie отсылаются на сервер только если запрос выполняется по протоколу SSL и HTTPS. Начиная с Chrome 52 и Firefox 52, незащищенные сайты (HTTP) не могут создавать куки с флагом secure .
Set-Cookie: PHPSESSID=m2iut9i59p73ld1c5q9j49c6t0; Secure
HttpOnly cookie не доступны из JavaScript через свойство document.cookie и через XMLHttpRequest , что помогает избежать межсайтового скриптинга (XSS). Рекомендуется устанавливать этот флаг для тех cookie, к которым не требуется обращаться через JavaScript. В частности, если куки используются только для поддержки сеанса, то в JavaScript они не нужны, так что в этом случае следует устанавливать флаг HttpOnly :
Set-Cookie: PHPSESSID=m2iut9i59p73ld1c5q9j49c6t0; Secure; HttpOnly
Область видимости cookie
Директивы domain и path определяют область видимости куки, то есть те URL, к которым куки могут отсылаться.
- Атрибут domain указывает хосты, к которым отсылаться куки. Если он не задан, то по умолчанию берется доменная часть документа (но без поддоменов). Если домен указан явно, то поддомены всегда включены. Например, если задано domain=server.com , то куки включены и в поддоменах, например, в blog.server.com .
- Атрибут path указывает URL, который должен быть в запрашиваемом ресурсе на момент отправки заголовка. Символ «/» интерпретируется как разделитель разделов, подразделы также включаются. Если задано path=/docs , то подходят и такие пути, как /docs , /docs/web , /docs/web/http .
Работа с cookie из JavaScript
Куки можно создавать через JavaScript при помощи свойства document.cookie . Если флаг HttpOnly не установлен, то и доступ к существующим cookies можно получить через JavaScript.
// получить cookie console.log(document.cookie);
PHPSESSID=m2iut9i59p73ld1c5q9j49c6t0; visitor=0d3749f09d222bea3b8f163937eb9bf1; lastvisit=1538919655
// установить cookie document.cookie = "some_name=some_value"; console.log(document.cookie);
PHPSESSID=m2iut9i59p73ld1c5q9j49c6t0; visitor=0d3749f09d222bea3b8f163937eb9bf1; lastvisit=1538919655; some_name=some_value
Функция getCookie()
Следующая функция возвращает cookie с именем name :
// возвращает cookie с именем name, если есть, если нет, то undefined function getCookie(name) var matches = document.cookie.match( new RegExp("(?:^|; )" + name.replace(/([\.$?*|<>\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)") ); return matches ? decodeURIComponent(matches[1]) : undefined; >
Функция setCookie()
function setCookie(name, value, options) options = options || >; var expires = options.expires; if (typeof expires == "number" && expires) var d = new Date(); d.setTime(d.getTime() + expires * 1000); expires = options.expires = d; > if (expires && expires.toUTCString) options.expires = expires.toUTCString(); > value = encodeURIComponent(value); var updatedCookie = name + " color:#FF0000">+ value; for (var propName in options) updatedCookie += "; " + propName; var propValue = options[propName]; if (propValue !== true) updatedCookie += " color:#FF0000">+ propValue; > > document.cookie = updatedCookie; >
Функция deleteCookie()
function deleteCookie(name) // удаляем вызовом setCookie() с датой в прошлом setCookie( name, "", expires: -1> ) >
Работа с cookie из PHP
Для сохранения cookie в браузере пользователя используется функция setcookie() :
bool setcookie( string $name, string $value, int $expire, string $path, string $domain, bool $secure, bool $httponly );
Может принимать следующие параметры:
- name : имя cookie, которое будет использоваться для доступа к его значению.
- value : значение или содержимое cookie — любой алфавитно-цифровой текст не более 4 кБайт.
- expire (необязательный параметр): срок действия, после которого cookie уничтожаются. Если данный параметр не установлен или равен 0, то уничтожение cookie происходит после закрытия браузера.
- path (необязательный параметр): путь к каталогу на сервере, для которого будут доступны cookie. Если задать «/», cookie будут доступны для всего сайта. Если задать, например, /docs , cookie будут доступны из этого каталога и всех его подкаталогов ( /docs/web , /docs/web/http ). По умолчанию значением является текущий каталог, в котором устанавливаются cookie.
- domain (необязательный параметр): задает домен, для которого будут доступны cookie. Если это домен второго уровня, например, server.com , то cookie доступны для всего сайта server.com , в том числе и для его поддоменов типа blog.server.com . Если задан поддомен blog.server.com , то cookie доступны только внутри этого поддомена.
- secure (необязательный параметр): указывает на то, что значение cookie должно передаваться по протоколу HTTPS. Если задано true , cookie от клиента будет передано на сервер, только если установлено защищенное соединение. По умолчанию параметр равен false .
- httponly (необязательный параметр): если равно true , cookie будут доступны только через HTTP протокол. То есть cookie в этом случае не будут доступны из JavaScript. По умолчанию параметр равен false .
Чтобы получить cookie, можно использовать глобальный массив $_COOKIE . Для удаления cookie достаточно в качестве срока действия указать какое-либо время в прошлом:
setcookie('lastvisit', '', time() - 3600);
Чтобы к идентификатору сессии PHPSESSID не было доступа из JavaScript, нужно отредактировать файл php.ini :
; Name of the session (used as cookie name). ; http://php.net/session.name session.name = PHPSESSID ; Whether or not to add the httpOnly flag to the cookie, which makes ; it inaccessible to browser scripting languages such as JavaScript. ; http://php.net/session.cookie-httponly session.cookie_httponly = 1
Можно также использовать функцию ini_set() , чтобы установит флаг HttpOnly уже во время выполнения приложения:
ini_set('session.cookie_httponly', 1); session_start();
Еще одни способ изменить флаг HttpOnly — вызов функции session_set_cookie_params() перед session_start() :
session_set_cookie_params(/*. */); session_start();
Установить флаг Secure для PHPSESSID из php.ini :
; http://php.net/session.cookie-secure session.cookie_secure = 1
Установить флаг во время работы приложения:
ini_set('session.cookie_secure', 1); session_start();
session_set_cookie_params(/*. */); session_start();
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
- 1С:Предприятие (31)
- API (29)
- Bash (43)
- CLI (99)
- CMS (139)
- CSS (50)
- Frontend (75)
- HTML (66)
- JavaScript (150)
- Laravel (72)
- Linux (146)
- MySQL (76)
- PHP (125)
- React.js (66)
- SSH (27)
- Ubuntu (68)
- Web-разработка (509)
- WordPress (73)
- Yii2 (69)
- БазаДанных (95)
- Битрикс (66)
- Блог (29)
- Верстка (43)
- ИнтернетМагаз… (84)
- КаталогТоваров (87)
- Класс (30)
- Клиент (27)
- Ключ (28)
- Команда (68)
- Компонент (60)
- Конфигурация (62)
- Корзина (32)
- ЛокальнаяСеть (28)
- Модуль (34)
- Навигация (31)
- Настройка (140)
- ПанельУправле… (29)
- Плагин (33)
- Пользователь (26)
- Практика (99)
- Сервер (74)
- Событие (27)
- Теория (105)
- Установка (66)
- Файл (47)
- Форма (58)
- Фреймворк (192)
- Функция (36)
- ШаблонСайта (68)