Статьи

Введение в Cookies

Возможно, вы слышали о cookie-файлах, но что именно они и что мы можем на самом деле делать с ними? В этом руководстве мы сосредоточимся на основах файлов cookie и узнаем об их функциональности в различных веб-приложениях и средах сайтов. Мы также узнаем, как использовать их в наших проектах PHP и JavaScript, уделяя при этом особое внимание вопросам безопасности, которые могут возникнуть при их использовании. Прочитав это, вы приобретете необходимый набор навыков для безопасного внедрения файлов cookie в ваши собственные веб-приложения.


Первый шаг в нашем путешествии — узнать, что на самом деле представляют собой эти файлы cookie! Даже если вы уже работали с ними, вы все равно можете найти эту часть весьма полезной — так что оставайтесь со мной!

Вы можете наиболее легко представить файлы cookie как текстовые файлы, которые сохраняются на вашем компьютере. По запросу веб-сервера ваш браузер создает такой файл. После этого веб-сервер может читать и записывать содержимое из этого файла. Хотя это кажется опасной функцией — в конце концов, никто не любит, когда другие люди пишут файлы на свой компьютер, но есть несколько ограничений, чтобы сделать этот процесс максимально безопасным.

  • Веб-серверы могут получать доступ только к файлам cookie, которые настроены на их собственный домен. Этот домен задается браузером, когда веб-сервер запрашивает новый файл cookie, и может быть только доменом или поддоменом веб-сервера (веб-сервер может выбрать поддомен, если он этого хочет). Это означает, что файлы cookie, которые были установлены, например, google.com, не могут быть прочитаны mozilla.com, и наоборот.
  • Согласно протоколу HTTP, размер файлов cookie не может превышать 4096 байт (4 КБ) каждый.
  • Существует ограничение на количество файлов cookie на домен. Количество зависит от браузера, однако обычно используется ограничение в двадцать файлов cookie. Это сделано для того, чтобы один домен не занимал место на диске клиента.
  • Существует ограничение на общее количество файлов cookie на жестком диске клиента. Это число также отличается для каждого браузера, но обычно оно ограничено тремя сотнями файлов cookie. Когда это число превышено, старый куки удаляется перед созданием нового.

Куки имеют срок годности. Эта дата установлена, чтобы браузер мог удалять старые куки, когда они больше не нужны веб-серверу. Если срок годности пуст, cookie будет удален при закрытии соединения с сервером. Это происходит, когда пользователь закрывает окно или вкладку сайта или когда пользователь закрывает весь браузер. Эти куки, иногда называемые сеансовыми куки, в основном используются для хранения временных настроек.

Давайте выясним, как эти вещи выглядят на техническом уровне. Файлы cookie передаются по протоколу HTTP . Это протокол, используемый браузерами для получения и отправки файлов на сервер. После того, как cookie был запрошен, он отправляется на сервер каждый раз, когда браузер выбирает новый элемент на веб-странице. Ниже мы можем увидеть фрагмент сервера, запрашивающего новый файл cookie (этот фрагмент является частью HTTP-ответа).

1
Set-Cookie: Name=content data;

Теперь не пугайтесь, это все очень понятно!

  • Set-Cookie: позволяет браузеру узнать, что сервер хочет создать новый cookie.
  • Имя — это имя файла cookie. Каждый файл cookie в домене должен иметь свое имя, поэтому браузер может хранить все файлы cookie отдельно. После имени следует = данные содержимого, где «данные содержимого» — это данные, которые должны содержаться в файле cookie. Эти данные могут быть текстовой строкой или числом и, как сказано, могут быть размером до 4 КБ.
  • expires = это команда для даты истечения срока действия. Дата окончания срока действия указана в формате «Wdy, DD-Mon-YYYY HH: MM: SS GMT» (не спрашивайте меня, почему он был определен для этого смешного формата, потому что я тоже не знаю. Ни один пользователь никогда не видит дата истечения срока действия, так зачем тратить память, пространство на жестком диске и пропускную способность на длинные даты?). Не беспокойтесь об этом, потому что большинство языков программирования имеют простые в использовании функции, доступные вам. Браузер автоматически удаляет куки с датой истечения в прошлом.
  • Домен и путь требуют более глубокого объяснения. Домен — это домен, в котором cookie будет активен. Если доменом является «ads.google.com», файл cookie будет отправляться только на сервер этого домена, а если доменом является «google.com», файл cookie будет отправляться на любой сервер любого из поддоменов домена. Google, включая сам google.com.
  • Путь — это путь домена, в который отправляется файл cookie. Это означает, что если для пути задано значение «/ images /», а для домена задано «ads.google.com», файл cookie будет отправляться на сервер только в том случае, если браузер запрашивает файл у «ads.google». .com / изображения /». Если для пути задано значение «/», файл cookie будет отправлен на сервер независимо от местоположения запрошенного файла на сервере.

На следующем шаге мы рассмотрим, как эти свойства можно использовать в языках программирования.


Файлы cookie могут быть созданы разными способами, но для целей данного руководства мы сосредоточимся на PHP и JavaScript.

При создании файла cookie в PHP важно помнить, что вы должны установить все файлы cookie, прежде чем отправлять какие-либо данные в браузер . Это означает, что вы должны всегда инициализировать новые куки перед любым выводом. Это включает в себя команды echo () или print () и теги <html> или <body>. Конечно, есть некоторые исключения, но это общее правило.

1
<?php /***Creating a cookie***/ $name = ‘clientname’;

Это должно показаться знакомым, за исключением $ secure и $ httponly . «Безопасный» — заставить куки отправляться только в том случае, если установлено соединение HTTPS, если установлено значение «истина» и обычно должно быть установлено значение «ложь». «Httponly» делает куки доступными только по протоколу HTTP, а это означает, что клиентские языки, такие как JavaScript и VBscript, не могут получить доступ к куки. Это помогает предотвратить неприятные вещи, такие как межсайтовый скриптинг , и должно быть установлено в true, если у вас нет намерений редактировать cookie-файлы на стороне клиента с помощью языка, такого как JavaScript. Кроме того, чтобы предотвратить неправильные представления, «httponly» не означает, что куки не могут быть отправлены через HTTPS, потому что они на самом деле могут. Тем не менее, обратите внимание, что приведенный выше фрагмент может быть значительно меньше (и должен быть):

1
2
3
<?php
setcookie( ‘clientname’, ‘Peter Griffin’, time()+60*30, ‘/example/’, ‘test.envato.com’, false,true);
?>

Большой! Теперь мы можем создавать файлы cookie, но мы также должны иметь возможность их читать. К счастью для нас, PHP делает это очень легко, когда cookie уже создан. В PHP есть переменная среды $ _COOKIE [], которую можно использовать для извлечения значения cookie. Чтобы использовать его, просто вставьте имя куки в скобках [] примерно так:

1
2
3
<?php
$cookieValue = $_COOKIE[‘name of the cookie’];
?>

Эта переменная окружения может использоваться как любая другая. Точно так же, как $ _GET [] и $ _POST [], он может быть обработан напрямую как обычная переменная (если вы проверите, действительно ли файл cookie существует), если хотите.

Если вы хотите изменить дату истечения срока действия, путь или домен, вы должны перезаписать существующий файл cookie с помощью setcookie (), используя то же имя, что и исходный файл cookie. Если вы измените дату истечения срока действия на прошлую (например, time () — 30 * 60), файл cookie будет удален.

Файлы cookie могут быть прочитаны и написаны на стороне клиента. Хотя JavaScript не предлагает хорошее решение для чтения и записи файлов cookie, оно возможно и широко используется. JavaScript использует объект document.cookie для манипулирования файлами cookie, как показано в следующем фрагменте:

1
2
3
4
5
//get current date
var expiredate = new Date();
//increase date by 5 hours
expiredate.setHours( expiredate.getHours() + 5);
document.cookie = ‘cookiename=cookievalue;

Как вы могли заметить, этот синтаксис очень похож на нотацию протокола HTTP. Это имеет то преимущество, что больше контролирует, но также создает некоторые потенциальные проблемы. Ниже приведен фрагмент <painful> для чтения cookie.

01
02
03
04
05
06
07
08
09
10
11
12
var cookieName = ‘testcookiename’;
var textArray = document.cookie.split(‘;’);
for(var i = 0; i < textArray.length; i++){ // loop though all string pieces
var textPiece = textArray[i];
 //filter beginning spaces
while(textPiece(0)==’ ‘) textPiece = textPiece.substring(1,textPiece.length);
//if the textpiece contains our cookies name
if (textPiece.indexOf(cookieName)== 0){
 //return whats after the cookies name
return textPiece.substring(cookieName.length,c.length);
}
}

Я знаю я знаю; это боль. К счастью для вас, ребята, я публикую ниже некоторые заранее написанные функции (вы, возможно, захотите создать свои собственные функции для целей обучения, и вам следует!).

01
02
03
04
05
06
07
08
09
10
11
12
13
14
function writeCookie(cookieName, cookieValue, expireHours, path, domain){
var date = new Date();
date.setHours(date.getHours + expireHours);
document.cookie = cookieName + ‘=’ + cookieValue + ‘;
}
 
function readCookie(cookieName){
var textArray = document.cookie.split(‘;’);
for(var i = 0; i < textArray.length; i++){
var textPiece = textArray[i];
while(textPiece(0)==’ ‘) textPiece = textPiece.substring(1,textPiece.length);
if (textPiece.indexOf(cookieName)== 0) return textPiece.substring(cookieName.length,c.length);
}
}

Помните, что эти фрагменты не содержат проверки ошибок.


Вы знали?
Файлы cookie были изобретены Netscape, которая хотела использовать их для создания корзины покупок для интернет-магазина. Благодаря cookie-файлам люди могли хранить товары в своей корзине даже после отключения от магазина.

В настоящее время мы используем файлы cookie практически для любых целей, о которых вы только можете подумать. Вы можете использовать их для сохранения пользовательских настроек, таких как имя, язык, местоположение или размер экрана. Это может улучшить качество сервиса, который вы хотите предоставить клиенту, потому что вы можете оптимизировать сервис для клиента и помнить эту оптимизацию в будущем. Например, вы можете сохранить предпочтительный язык клиента в файле cookie, а затем показывать содержимое вашего сайта на предпочитаемом языке каждый раз, когда клиент посещает ваш сайт.

Конечно, есть гораздо больше забавных вещей, которые можно сделать с куки, чем это! На следующем шаге я покажу вам пример классного фрагмента кода.


В заключение! Теперь мы можем начать писать отличный код! Ниже приведен фрагмент бонуса, который использует куки для создания механизма повторного входа.

Прежде чем мы начнем, этот фрагмент содержит некоторый код MySQL. Если вы не знакомы с MySQL, не паникуйте. Несмотря на то, что этот фрагмент немного сложен, он должен быть понятен с базовыми знаниями PHP и cookie.

Чтобы создать реализацию «помни меня», у нас должно быть несколько вещей. Во-первых, нам нужна таблица базы данных, содержащая имя пользователя, пароль и поле идентификации. Во-вторых, нам нужна уникальная строка или номер для безопасной идентификации клиентов с помощью файлов cookie (это идентификация в таблице базы данных). В этом фрагменте мы будем использовать дайджест SHA-1, который является просто строкой, в качестве идентификатора. При правильном использовании это обеспечивает превосходную безопасность.

Большинство людей просто вставляют имя пользователя и пароль в файл cookie и автоматически отправляют его на сервер. Этого следует избегать всегда! Куки-файлы обычно отправляются через незащищенное соединение, поэтому их могут легко увидеть любые потенциальные злоумышленники.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
 
//this assumes that the user has just logged in
/****Creating an identification string****/
 
$username;
 
//create a digest from two random values and the username
$digest = sha1(strval(rand(0,microtime(true)) + $username + strval(microtime(true));
 
//save to database (assuming connection is already made)
mysql_query(‘UPDATE users SET reloginDigest=»‘.$digest.'» WHERE username=»‘.$username.'»‘);
 
//set the cookie
setcookie( ‘reloginID’, $digest, time()+60*60*24*7,’/’, ‘test.example.com’, false, true);
 
 
//this assumes that the user is logged out and cookie is set
/****Verifying users through the cookie****/
 
$digest = $_COOKIE[‘reloginID’];
$digest = mysql_real_escape_string($digest);
 
//check database for digest
$result = mysql_query(‘SELECT username FROM users WHERE reloginDigest=»‘.$digest.'»‘);
//check if a digest was found
if(mysql_num_rows($result) == 1){
    $userdata = mysql_fetch_object($result);
    $username = $userdata->username;
 
    //here you should set a new digest for the next relogin using the above code!
 
    echo ‘You have successfully logged in, ‘.$username;
 
} else{
//digest didn’t exist (or more of the same digests were found, but that’s not going to happen)
echo «failed to login!»;
}
 
?>

При использовании дайджеста, как мы сделали, шансы получить два одинаковых дайджеста ничтожны. Дайджест — это строка из сорока символов, которая, по идее, всегда должна обеспечивать полный случайный вывод при изменении ввода. На практике вы должны добавить ограничение времени в коде на стороне сервера, чтобы дайджест стал недействительным через X минут. Это не позволяет злоумышленникам копировать чьи-то куки и использовать их для входа в систему.


Мы почти достигли конца этого урока. В заключение я хотел бы обобщить некоторые лучшие практики:

  • Никогда не вставляйте конфиденциальные данные в cookie. Клиент может просматривать на общедоступном компьютере, поэтому не оставляйте личную информацию позади.
  • Никогда не доверяйте данным, поступающим из куки. Всегда фильтруйте строки и числа! Злоумышленник может записать вредоносные данные в файл cookie, чтобы сделать то, что вы не хотите, чтобы ваш сервис делал.
  • Попробуйте оценить, как долго должен быть действителен cookie, и соответственно установить дату истечения срока действия. Вы не хотите загружать компьютер клиента старыми файлами cookie, срок действия которых истекает через сто лет.
  • Всегда устанавливайте безопасный и httponly для удовлетворения требований вашего приложения. Если ваше приложение не редактирует куки с помощью JavaScript, включите httponly. Если у вас всегда есть HTTPS-соединение, включите безопасный. Это улучшает целостность и конфиденциальность данных.

Я надеюсь, что вы немного узнали из сегодняшнего учебника Nettuts +. Если у вас есть какие-либо вопросы, не стесняйтесь оставить комментарий или сказать привет в Twitter .