Php-файлы cookie — настройка, доступ и удаление cookie
Содержание:
- Приложение: GDPR
- Как задать Cookie теория кратко:
- Аутентификация
- Что такое сессия в PHP?
- samesite
- Простой пример использования
- Parameter Values
- Сборка вешалки из фанеры
- Как прочитать\получить куку php?
- Получение значения куки
- Семья и дети Александра Градского
- Appendix: Third-party cookies
- Examples
- Работа с cookie из PHP
- Регистрация на сайте
Приложение: GDPR
Эта тема вообще не связана с JavaScript, но следует её иметь в виду при установке куки.
В Европе существует законодательство под названием GDPR, которое устанавливает для сайтов ряд правил, обеспечивающих конфиденциальность пользователей. И одним из таких правил является требование явного разрешения от пользователя на использование отслеживающих куки.
Обратите внимание, это относится только к куки, используемым для отслеживания/идентификации/авторизации. То есть, если мы установим куки, которые просто сохраняют некоторую информацию, но не отслеживают и не идентифицируют пользователя, то мы свободны от этого правила
То есть, если мы установим куки, которые просто сохраняют некоторую информацию, но не отслеживают и не идентифицируют пользователя, то мы свободны от этого правила.
Но если мы собираемся установить куки с информацией об аутентификации или с идентификатором отслеживания, то пользователь должен явно разрешить это.
Есть два основных варианта как сайты следуют GDPR. Вы наверняка уже видели их в сети:
-
Если сайт хочет установить куки для отслеживания только для авторизованных пользователей.
То в регистрационной форме должен быть установлен флажок «принять политику конфиденциальности» (которая определяет, как используются куки), пользователь должен установить его, и только тогда сайт сможет использовать авторизационные куки.
-
Если сайт хочет установить куки для отслеживания всем пользователям.
Чтобы сделать это законно, сайт показывает модально окно для пользователей, которые зашли в первый раз, и требует от них согласие на использование куки. Затем сайт может установить такие куки и показать пользователю содержимое страницы. Хотя это создаёт неудобства для новых посетителей – никому не нравится наблюдать модальные окна вместо контента. Но GDPR в данной ситуации требует явного согласия пользователя.
GDPR касается не только куки, но и других вопросов, связанных с конфиденциальностью, которые выходят за рамки материала этой главы.
Как задать Cookie теория кратко:
Чтобы задать Cookie, нужно иметь саму форму для отправки данных, в форме должен быть тег input с типом checkbox, рядом с которым чаще всего пишут запомнить меня , после нажатия котрого будет понятно, что человек хочет, чтобы Cookie были установлены!
Код формы для отправки согласия на установку Cookie:
<form method=»post» action=»»>
<input type=»checkbox» name=»test_2″> запомнить меня
<input type=»submit» name=»submit» value=»submit»>
</form>
Форма для отправки согласия на установку Cookie:
Теперь нам нужен код, который проверит нажат ли чекбокс или радиоточка…
if($_POST) { echo ‘ПРИВЕТ МИР!’; } //в фигурных скобках действие…
SetCookie if($_POST) { SetCookie («test_2″,»Value»,time()+60); }
Создаем условие, по которому будем проверять, установлена ли кука, или нет:
if(@$_COOKIE ){ echo ‘COOKIE благополучно созданы : ‘.$_COOKIE ;}else{ echo ‘Cookie еще не установлены! Нажмите отправить и здесь увидите результат!’}
Не забываем, что для получения данных из кук требуется вторая перезагрузка — разберем подробнее в пункте Как задать Cookie теория подробно:
Аутентификация
Процедура проверки возможности доступа пользователя к определенной части сайта и называется аутентификацией.
Весь процесс аутентификации всегда состоит из нескольких шагов:
- При попытке доступа к закрытой части сайта, пользователь видит форму, где он должен ввести свой логин и пароль.
- Форма отправляется, а полученные данные сравниваются с действительным логином и паролем существующего пользователя.
- Если данные совпадают, то пользователь считается аутентифицированным и получает доступ к приватной части сайта.
- При повторном открытии этой страницы пользователь не должен повторно вводить пароль, если он уже делал это в рамках текущего сеанса.
Ещё немного терминологии
Следует различать два термина: аутентификация и авторизация.
Аутентификация — проверка подлинности предоставленного пользователем идентификатора (пара логин-пароль).Авторизация — процесс проверки и предоставления прав пользователю на выполнение определённого действия.
Логика авторизации намного сложнее, чем простая проверка совпадения почты и пароля при входе на сайт. В авторизацию могут также входить следующие понятия: группы пользователей, виды действий, ресурсы, иерархия ролей и действий. Этой теме можно посвятить отдельную главу. Мы не рассматриваем авторизацию в рамках этого учебника, потому что эта тема выходит за рамки «базовой».
Что такое сессия в PHP?
Сессия — это механизм для сохранения информации на разных веб-страницах для идентификации пользователей пока они бродят по сайту или приложению. Вам интересно, почему сеансы нужны для веб-сайта? Чтобы понять, почему сеансы необходимы, нам нужно чуть вернуться назад и посмотреть, как работает HTTP-протокол.
Протокол HTTP — это протокол без учета состояния, что означает, что сервер не может сопоставить конкретного пользователя по несколькими запросами. Например, при доступе к веб-странице, сервер несёт ответственность за предоставление содержимого запрашиваемой страницы. Поэтому, когда вы обращаетесь к другим страницам одного и того же веб-сайта, веб-сервер интерпретирует каждый запрос отдельно, как если бы они не были связаны друг с другом. Серверу не известно, что каждый запрос исходит от одного и того же пользователя.
Следующая диаграмма вкратце изображает протокол HTTP.
В этой модели, если вы хотите отобразить пользовательскую информацию, вам нужно будет аутентифицировать пользователя в каждом запросе. Представьте, что вам нужно было вводить ваше имя пользователя и пароль на каждой странице с информацией ваших о данных! Да, это было бы громоздко и вообще не практично, и именно здесь на помощь приходят сеансы.
Сессия позволяет вам обмениваться информацией с разными страницами одного сайта или приложения, и помогает поддерживать состояние. Это позволяет серверу знать, что все запросы исходят от одного и того же пользователя, что позволяет сайту отображать информацию и настройки пользователя.
Давайте быстро рассмотрим общий пример входа на веб-сайт, чтобы понять, что происходит за кулисами.
- Пользователь открывает страницу входа на веб-сайт.
- После отправки формы входа, сервер, на другом конце, аутентифицирует запрос, проверив введённые учётные данные.
- Если учётные данные, введённые пользователем, верны, сервер создаёт новый сеанс. Сервер генерирует уникальное случайное число, которое называется идентификатором сеанса. Также, на сервере, создаётся новый файл, который используется для хранения информации, относящейся к сеансу.
- Затем, идентификатор сеанса передаётся обратно пользователю, вместе с тем, что он запросил. За кулисами этот идентификатор сеанса отправляется в заголовке ответа «куки» (так называется по умолчанию).
- Когда браузер получает ответ от сервера, он получает заголовок куки-файла . Если в браузере разрешены «куки», то он сохранит этот , в котором хранится идентификатор сеанса, переданный сервером.
- Для последующих запросов, «кука» передаётся обратно на сервер. Когда сервер получает «куку» , он пытается инициализировать сеанс с этим идентификатором сеанса. Он делает это, загружая файл сеанса, который был создан ранее во время инициализации сеанса. Затем он инициализирует суперглобальную переменную массива с данными, хранящимися в файле сеанса.
Таким образом, пользовательские данные сохраняются даже в нескольких запросах, и пользователь не теряется на протяжении всего сеанса.
На следующей диаграмме показано, как протокол HTTP работает с сеансами.
Теперь, когда вы увидели краткое введение в работу сессий, мы создадим несколько практических примеров, чтобы продемонстрировать, как создавать и манипулировать переменными сессии.
samesite
That’s another security attribute . It’s designed to protect from so-called XSRF (cross-site request forgery) attacks.
To understand how it works and when it’s useful, let’s take a look at XSRF attacks.
Imagine, you are logged into the site . That is: you have an authentication cookie from that site. Your browser sends it to with every request, so that it recognizes you and performs all sensitive financial operations.
Now, while browsing the web in another window, you accidentally come to another site . That site has JavaScript code that submits a form to with fields that initiate a transaction to the hacker’s account.
The browser sends cookies every time you visit the site , even if the form was submitted from . So the bank recognizes you and actually performs the payment.
That’s called a “Cross-Site Request Forgery” (in short, XSRF) attack.
Real banks are protected from it of course. All forms generated by have a special field, so called “XSRF protection token”, that an evil page can’t generate or extract from a remote page (it can submit a form there, but can’t get the data back). And the site checks for such token in every form it receives.
But such protection takes time to implement: we need to ensure that every form has the token field, and we must also check all requests.
The cookie option provides another way to protect from such attacks, that (in theory) should not require “xsrf protection tokens”.
It has two possible values:
samesite=strict (same as samesite without value)
A cookie with is never sent if the user comes from outside the same site.
In other words, whether a user follows a link from their mail or submits a form from , or does any operation that originates from another domain, the cookie is not sent.
If authentication cookies have option, then XSRF attack has no chances to succeed, because a submission from comes without cookies. So will not recognize the user and will not proceed with the payment.
The protection is quite reliable. Only operations that come from will send the cookie, e.g. a form submission from another page at .
Although, there’s a small inconvenience.
When a user follows a legitimate link to , like from their own notes, they’ll be surprised that does not recognize them. Indeed, cookies are not sent in that case.
We could work around that by using two cookies: one for “general recognition”, only for the purposes of saying: “Hello, John”, and the other one for data-changing operations with . Then a person coming from outside of the site will see a welcome, but payments must be initiated from the bank website, for the second cookie to be sent.
samesite=lax
A more relaxed approach that also protects from XSRF and doesn’t break user experience.
Lax mode, just like , forbids the browser to send cookies when coming from outside the site, but adds an exception.
A cookie is sent if both of these conditions are true:
-
The HTTP method is “safe” (e.g. GET, but not POST).
The full list of safe HTTP methods is in the RFC7231 specification. Basically, these are the methods that should be used for reading, but not writing the data. They must not perform any data-changing operations. Following a link is always GET, the safe method.
-
The operation performs top-level navigation (changes URL in the browser address bar).
That’s usually true, but if the navigation is performed in an , then it’s not top-level. Also, JavaScript methods for network requests do not perform any navigation, hence they don’t fit.
So, what does is basically allows a most common “go to URL” operation to have cookies. E.g. opening a website link from notes satisfies these conditions.
But anything more complicated, like a network request from another site or a form submission loses cookies.
If that’s fine for you, then adding will probably not break the user experience and add protection.
Overall, is a great option, but it has an important drawback:
samesite is ignored (not supported) by old browsers, year 2017 or so.
So if we solely rely on to provide protection, then old browsers will be vulnerable.
But we surely can use together with other protection measures, like xsrf tokens, to add an additional layer of defence and then, in the future, when old browsers die out, we’ll probably be able to drop xsrf tokens.
Простой пример использования
В данном примере мы сделали страницу, которая запрашивает Ваше имя при первом посещении, затем она сохраняет Ваше имя в куки и показывает его при следующих посещениях.
Откройте страницу в новом окне. При первом посещении она попросит ввести имя и сохранит его в куки. Если Вы посетите страницу еще раз, она отобразит на экране введенное имя из куки.
Для куки задаем срок хранения в 1 год от текущей даты, это означает, что браузер сохранит Ваше имя даже если Вы закроете его.
Вы можете удалить куки нажав на ссылку Забудь обо мне!, которая вызывает функцию и обновляет страницу, чтобы снова запросить имя у Вас.
Вы можете посмотреть код страницы в браузере, выбрав функцию просмотра исходного кода. Здесь приводится основная часть кода:
Parameter Values
Parameter | Description |
---|---|
name | Required. Specifies the name of the cookie |
value | Optional. Specifies the value of the cookie |
expire | Optional. Specifies when the cookie expires. The value: time()+86400*30, will set the cookie to expire in 30 days. If this parameter is omitted or set to 0, the cookie will expire at the end of the session (when the browser closes). Default is 0 |
path | Optional. Specifies the server path of the cookie. If set to «/», the cookie will be available within the entire domain. If set to «/php/», the cookie will only be available within the php directory and all sub-directories of php. The default value is the current directory that the cookie is being set in |
domain | Optional. Specifies the domain name of the cookie. To make the cookie available on all subdomains of example.com, set domain to «example.com». Setting it to www.example.com will make the cookie only available in the www subdomain |
secure | Optional. Specifies whether or not the cookie should only be transmitted over a secure HTTPS connection. TRUE indicates that the cookie will only be set if a secure connection exists. Default is FALSE |
httponly | Optional. If set to TRUE the cookie will be accessible only through the HTTP protocol (the cookie will not be accessible by scripting languages). This setting can help to reduce identity theft through XSS attacks. Default is FALSE |
Сборка вешалки из фанеры
Как прочитать\получить куку php?
То, что в браузере отображается кука, это хорошо, но мы ведь ее создаем, чтобы впоследствии использовать в наших скриптах. Так как же получить куку? Для этого существует глобальный массив кук $_COOKIE, в котором находятся вообще все созданные куки. Обратиться к ним легко — достаточно знать имя.
Попробуем прочитать содержимое нашей куки wpguru. Для этого напишем простенький скриптик:
1 |
if(isset($_COOKIE’wpguru’)){ echo’Кука wpguru существует, и в ней лежит значение: ‘.$_COOKIE’wpguru’; } else{ echo’Кука wpguru не задана’; } |
И глянем, что вывелось на экран:
Как видите, все прекрасно работает. Вот так можно с легкостью проверить, существует ли нужная кука, и если да, то взять ее значение.
Рекомендую всегда делать проверку на существования необходимых переменных, массивов, и тд. Так Вы избежите обидных ошибок в будущем.
Получение значения куки
Для того, чтобы получить значение предварительно установленного куки для текущего документа, нужно использовать свойство :
Таким образом возвращается строка, которая состоит из списка пар имя/значение, разделенных точкой с запятой для всех куки, которые действуют для текущего документа. Например:
В данном примере 2 куки, которые были предварительно установлены: , который имеет значение , и , который имеет значение .
Функция для получения значения куки
Обычно, нам нужно только значение одного куки за один раз. Поэтому строка куки не удобна для использования! Здесь приводится функция, которая обрабатывает строку , возвращет только то куки, которое представляет интерес в конкретный момент:
Данная функция использует регулярное выражение для поиска имени куки, которое представляет интерес, а затем возвращает значение, которое обработано функцией для перекодирования к нормальному символьному виду. (Если куки не найдено, возвращается значение null.)
Данная функция проста в использовании. Например, для возврата значения куки :
Семья и дети Александра Градского
Семья и дети Александра Градского – это то, что в настоящее время занимает особое место в его жизни. В настоящее время Семья композитора состоит из жены Марины и троих детей – Даниила, Александра и Марии Градских.
Напомним, что Даниил и Мария Градские – уже давно взрослые люди и на сегодняшний день одни также, как и их отец, работают в области шоу-бизнеса, хоть и не смогли достичь в нем таких высот, как и он. Хотя, справедливости ради, стоит упомянуть, что они ни к чему подобному и не стремились. Кроме того, не стоит забывать и о самом младшем наследнике музыканта, которого ему подарила последняя жена – Марина.
A cookie is called “third-party” if it’s placed by domain other than the page user is visiting.
For instance:
-
A page at loads a banner from another site: .
-
Along with the banner, the remote server at may set header with cookie like . Such cookie originates from domain, and will only be visible at :
-
Next time when is accessed, the remote server gets the cookie and recognizes the user:
-
What’s even more important, when the users moves from to another site that also has a banner, then gets the cookie, as it belongs to , thus recognizing the visitor and tracking him as he moves between sites:
Third-party cookies are traditionally used for tracking and ads services, due to their nature. They are bound to the originating domain, so can track the same user between different sites, if they all access it.
Naturally, some people don’t like being tracked, so browsers allow to disable such cookies.
Also, some modern browsers employ special policies for such cookies:
- Safari does not allow third-party cookies at all.
- Firefox comes with a “black list” of third-party domains where it blocks third-party cookies.
Please note:
If we load a script from a third-party domain, like , and that script uses to set a cookie, then such cookie is not third-party.
If a script sets a cookie, then no matter where the script came from – the cookie belongs to the domain of the current webpage.
Examples
Session cookies are removed when the client shuts down. Cookies are session cookies if they don’t specify the or attributes.
Set-Cookie: sessionId=38afes7a8
Instead of expiring when the client is closed, permanent cookies expire at a specific date () or after a specific length of time ().
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT
Set-Cookie: id=a3fWa; Max-Age=2592000
Invalid domains
A cookie for a domain that does not include the server that set it .
The following cookie will be rejected if set by a server hosted on :
Set-Cookie: qwerty=219ffwef9w0f; Domain=somecompany.co.uk
A cookie for a sub domain of the serving domain will be rejected.
The following cookie will be rejected if set by a server hosted on :
Set-Cookie: sessionId=e8bb43229de9; Domain=foo.example.com
Cookie prefixes
Cookies names prefixed with or can be used only if they are set with the attribute from a secure (HTTPS) origin.
In addition, cookies with the prefix must have a path of (meaning any path at the host) and must not have a attribute.
For clients that don’t implement cookie prefixes, you cannot count on these additional assurances, and prefixed cookies will always be accepted.
// Both accepted when from a secure origin (HTTPS) Set-Cookie: __Secure-ID=123; Secure; Domain=example.com Set-Cookie: __Host-ID=123; Secure; Path=/ // Rejected due to missing Secure attribute Set-Cookie: __Secure-id=1 // Rejected due to the missing Path=/ attribute Set-Cookie: __Host-id=1; Secure // Rejected due to setting a Domain Set-Cookie: __Host-id=1; Secure; Path=/; Domain=example.com
Для сохранения cookie в браузере пользователя используется функция :
bool setcookie( string $name, string $value, int $expire, string $path, string $domain, bool $secure, bool $httponly );
Может принимать следующие параметры:
- : имя cookie, которое будет использоваться для доступа к его значению.
- : значение или содержимое cookie — любой алфавитно-цифровой текст не более 4 кБайт.
- (необязательный параметр): срок действия, после которого cookie уничтожаются. Если данный параметр не установлен или равен 0, то уничтожение cookie происходит после закрытия браузера.
- (необязательный параметр): путь к каталогу на сервере, для которого будут доступны cookie. Если задать «/», cookie будут доступны для всего сайта. Если задать, например, , cookie будут доступны из этого каталога и всех его подкаталогов (, ). По умолчанию значением является текущий каталог, в котором устанавливаются cookie.
- (необязательный параметр): задает домен, для которого будут доступны cookie. Если это домен второго уровня, например, , то cookie доступны для всего сайта , в том числе и для его поддоменов типа . Если задан поддомен , то cookie доступны только внутри этого поддомена.
- (необязательный параметр): указывает на то, что значение cookie должно передаваться по протоколу HTTPS. Если задано , cookie от клиента будет передано на сервер, только если установлено защищенное соединение. По умолчанию параметр равен .
- (необязательный параметр): если равно , cookie будут доступны только через HTTP протокол. То есть cookie в этом случае не будут доступны из JavaScript. По умолчанию параметр равен .
Чтобы получить cookie, можно использовать глобальный массив . Для удаления cookie достаточно в качестве срока действия указать какое-либо время в прошлом:
setcookie('lastvisit', '', time() - 3600);
Чтобы к идентификатору сессии не было доступа из JavaScript, нужно отредактировать файл :
; 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('session.cookie_httponly', 1); session_start();
Еще одни способ изменить флаг — вызов функции перед :
session_set_cookie_params(/*...*/); session_start();
Установить флаг для из :
; http://php.net/session.cookie-secure session.cookie_secure = 1
Установить флаг во время работы приложения:
ini_set('session.cookie_secure', 1); session_start();
session_set_cookie_params(/*...*/); session_start();
Поиск:
Cookie • HTTP • HTTPS • JavaScript • PHP • Web-разработка • expire • httponly • localStorage • php.ini • secure • sessionStorage • setcookie
Регистрация на сайте
Перед тем, как мы начнем добавлять аутентификацию на своем сайте, придётся добавить форму для регистрации нового аккаунта.Аккаунт — это учётная запись пользователя.
Чтобы завести аккаунт, требуется пройти регистрацию — это заполнение специальной формы, где пользователь указывает свою почту, пароль, и, возможно, дополнительную информацию.
После регистрации все данные из формы сохраняются в базе данных как есть
Но хранению паролей нужно уделить особое внимание
Хранение паролей
Пароль пользователя — это секретный набор символов, который используется в дальнейшем в ходе аутентификации. Зная пароль пользователя, злоумышленник может войти на сайт под его именем. По этой причине пароль нельзя хранить в базе в открытом виде. Ведь если информацию из БД сайта украдут, то
данные всех пользователей станут скомпрометированными.
Вместо самого пароля, в базе будут храниться их отпечатки — хэши.
Что такое хеширование
Отпечаток (хэш) — это результат работы функции хэширования, которая вернёт для любого значения строку фиксированной длины.
Используя специальный математический алгоритм, такая функция умеет преобразовывать любую переданную информацию к строке фиксированной длины (например, 32 или 64 символа). Причём любому массиву информации, будь это все статьи из Википедии, или одно слово, всегда будет соответствовать уникальный отпечаток. Повторный вызов функции для одного и того же исходника всегда возвращает один и тот же хэш.
Обратная операция (получить из отпечатка оригинал) невозможна.
Возьмём простой пример. У нас есть информация, для которой мы хотим получить отпечаток. Пусть такой информацией будет следующая строка:
«Я знаю только то, что ничего не знаю, но другие не знают и этого»
Результат обработки этой строки хэширующей функцией SHA-1 будет таким:
Хэширующие функции часто используются для контроля целостности информации при передачи по сети. Например, чтобы убедиться в том, что загруженный файл не был повреждён, достаточно получить его хэш и сравнить данный хэш с опубликованным на сайте. Если в файле поменялся хоть один байт, то эти отпечатки будут совершенно разными.
Нам же функции хэширования помогут для сравнения паролей.
Реализация регистрации пользователя
Вернёмся к форме регистрации.
Выше говорилось, что вместо пароля лучше хранить его отпечаток. Для получения отпечатка существуют множество хэшируюших функций. К счастью, нам не надо разбираться в их многообразии, потому что в PHP есть стандартная функция, которая делает ровно то, что нужно.
Вот пример как из пароля получить отпечаток, пригодный для хранения в базе:
Вызов этой функции вернёт следующую строку:
Именно это значение и следует хранить в БД, вместо пароля.