Контент


Ko3: работа с cookies

Предлагаю вашему вниманию небольшую заметку о работе с куками в Kohana v3. Наверняка вы знаете, что для этого в Ko3 имеется специальный хэлпер Cookie. Как обычно, сперва рассмотрим его методы.

Тут все привычно и понятно

  • set($name, $value, $expiration = NULL)


    Устанавливает куку по имени $name в значение $value (на самом деле не совсем так, об этом позже). Параметр $expiration необязательный, он предназначен для указания срока актуальности куки. Например, если установить $expiration в 30, то получится время жизни 30 секунд от момента установки. Если параметр сделать равным нулю, то кука сохранится без времени жизни и удалится по окончании сессии браузера. Если же его вообще опустить, то будет взято значение по умолчанию — свойство Cookie::$expiration. Изначально оно равно нулю, но так как оно public, то его можно поменять под себя.
    Если установка куки прошла успешно, возвращается TRUE, иначе FALSE.

  • get($key, $default = NULL)


    Возвращает куку по имени $key, а если не найдена — значение $default.

  • delete($name)


    Удаляет куку $name. Происходит это следующим образом — текущее значение обнуляется, время жизни передается отрицательное (т.е. кука уже просрочена).

    Важно понимать, что при установке куки (классическим setcookie() или Cookie::set() — без разницы) новое значение будет установлено только после перезагрузки страницы (точнее после отправки HTTP-заголовков). Текущее же значение так и останется нетронутым в глобальном массиве $_COOKIE. Помните об этом, т.к. Cookie::set() изменяет только будущую куку, Cookie::get() пытается найти текущую, а Cookie::delete() удаляет как текущую, так и отправляемую.

Дополнительные параметры

В данном классе есть публичные статичные свойства, которые могут быть полезными при работе с куками. Одно из них (Cookie::$expiration) я уже упомянул, вот прочие:

  • $path (‘/‘ по умолчанию). Используется для указания пути, для которого доступна кука. Например:

    Cookie::$path = '/'; // кука доступна для всего содержимого домена
    Cookie::$path = '/first/'; // кука видна только в папке first и ее содержимом

  • $domain (NULL по умолчанию). Позволяет четко указать, для какого домена использовать куку. Например, для успешного использования кук поддоменами, надо указать имя родительского домена, предварив его точкой, например так:

    Cookie::$domain = '.first.com'; // кука будет доступна в доменах first.com, second.first.com и т.д.
    Cookie::$domain = 'second.first.com'; // куки будут недоступны для домена first.com!!

  • $secure (FALSE по умолчанию). По названию понятно, что используется для безопасной отправки кук. Заголовки с куками будут отправлены только если используется протокол HTTPS.
  • $httponly (FALSE по умолчанию). Это тоже опция безопасности. Если установить в TRUE, то доступ к кукам будет осуществляться только посредством HTTP-заголовков (т.е. отсекаются скриптовые языки, например JavaScript).

Изюминка

А зачем же тогда класс Cookie нужен, если он по сути не отличается от «родной» функции setcookie()? Так вот, данный класс позволяет дополнительно шифровать куки, а точнее — подписывать их. Дело в том, что метод Cookie::set() отправляет не переданное значение $value, а более сложную конструкцию, состоящую из двух частей — собственно значение и его подпись.

Вот, например, как выглядит у меня кука по имени ‘test1‘ и значением 1:
8f72531079624b276ca56e21b3162a648ba20431~1
Первая часть (до тильды) — это и есть таинственная подпись, потом идет нешифрованное значение — единица. В чем смысл? Разработчики постарались обезопасить куки от подмены значения. Когда мы передаем в Cookie::set() переменную, хэлпер формирует строковое значение из имени браузера ($_SERVER['HTTP_USER_AGENT']), имени куки и нового значения и генерирует хэш от полученной строки. В результате получается подпись для куки.
Обратите внимание, что само по себе значение ни от кого не прячется — оно доступно, просто откиньте тильду. Но вот если кто-то попробует подменить значение, то сгенерированная заново подпись не совпадет с переданной в куке — так система определит подмену и просто отбросит куку.

Все вышеуказанные действия по формировании подписи осуществляются в методе salt($name, $value). Помимо вышеперечисленных «ингредиентов», перед хэшированием добавляется соль — значение параметра Cookie::$salt. Это, как и в модуле Auth, позволяет усложнить возможный подбор подписи куки, т.к. сам алгоритм известен. Просто поменяйте значение по умолчанию на какое-то свое, и никто не сможет изменить ваши подписанные куки.

С подписью кук могут возникнуть проблемы, если в вашем проекте предполагается установка кук посредством JavaScript. Конечно, можно портировать алгоритм формирования подписи из php, чтобы кука не отбрасывалась после установки, но тогда вам придется опубликовать и соль, что неприемлимо. Если все же очень хочется писать куки из скрипта, есть вариант немного переписать класс Cookie, чтобы он мог принимать и неподписанные куки (определять по отсутствию тильды в значении).

На этом все, класс небольшой и совсем не страшный :)

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Опубликовано в Kohana3.

Теги: , , .


Комментарии (9)

Будьте в курсе обсуждения, подпишитесь на RSS ленту комментариев к этой записи.

  1. Slaver пишет:

    Меня, как раз, это обязательное засаливания кук очень удивило в свой время. Это можно было сделать дополнительной опцией, но не обязательной.

  2. Максим Нагайченко пишет:

    А еще этот класс юзается при работе с сессией! А также саму сессию можно хранить в куках, конечно 4096 байт ограничение, но всё же…

    Вообще много фреймов оборачивают нативные ф-ции пыха, тем самым допиливая и расширяя их.

    Рекомендую всем юзать именно ф-ции фрейма, чем нативные, ну если они обернуты.

  3. Slaver пишет:

    Рекомендую всем юзать именно ф-ции фрейма, чем нативные, ну если они обернуты.

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

  4. Максим Нагайченко пишет:

    @Slaver О! я за тобой даже в твиттере следую ))

    Я пока не имел трудностей с Куками в кохане, а вот с сессией, точнее Auth вот тут есть какие-то проблемки (вылетаю через несколько обновлений страниц)

  5. Slaver пишет:

    С куками проблема может быть в том, если пробуешь использовать сторонние, в которых никакие секюрные штуки Kohana не задуманы. Я один раз сильно тупил, почему ничего не работает — потом понял. Т.е., повторюсь, обязательное добавление соли в куки — не очевидный процесс и совсем не обязательный.

    ЗЫ За мной следят ))

  6. stalker пишет:

    @Максим Нагайченко
    проблемы могут появиться если с Cookies потребуется работать через JS. WordPress, например, активно меняет значения Cookies таким образом .. с ‘подписью’ такие трюки работать уже не будут.

  7. Максим пишет:

    @stalker Ну везде можно найти ложку дёгтя. Можно конечно и извернуться… через аякс ))))

  8. stalker пишет:

    @Максим
    не-не-не .. в этом случае я согласен с Slaver — лучше бы класс в Kohana был настраиваемым. из-за его отсутствия пришлось писать свой ‘велосипедик’ :)

  9. biakaveron пишет:

    Собственно об этом я и писал в конце статьи. Только не совсем отказаться от подписывания, а комбинировать оба метода.



Можно включить подсветку кода: <code><pre lang="">...</pre></code>
Разрешены некоторые HTML теги

или используйте trackback.