Глава 35. Cookies

PHP прозрачно поддерживает HTTP cookies. Cookies это механизм хранения данных броузером удаленной машины для отслеживания или идентификации возвращающихся посетителей. Вы можете установить cookies при помощи функций setcookie() или setrawcookie(). Cookies являются частью HTTP-заголовка, поэтому setcookie() должна вызываться до любого вывода данных в броузер. Это то же самое ограничение, которое имеет функция header(). Вы можете использовать функции буферизации вывода, чтобы задержать вывод результатов работы скрипта до того момента, когда будет известно, понадобится ли установка cookies или других HTTP-заголовков.

Любые cookies, отправленные серверу броузером клиента, будут автоматически преобразованы в переменные PHP, подобно данным методов GET и POST. На этот процесс влияют конфигурационные директивы register_globals и variables_order . Для назначения нескольких значений одной cookie, просто добавьте [] к её имени.

В PHP 4.1.0 и выше, глобальный массив $_COOKIE всегда автоматически заполняется значениями полученных cookies. В более ранних версиях определяется массив $HTTP_COOKIE_VARS но только когда включена директива track_vars. (Эта директива всегда включена начиная с PHP 4.0.3.)

Дополнительная информация, в том числе и об особенностях реализации броузеров, приведена в описании функций setcookie() и setrawcookie().



Cookies
kalla_durga at gmail dot com
03-Feb-2006 12:10
In response to the solution posted in the comment below, there are some practical issues with this solution that must be kept in mind and handled by your code. I developed an application using a similar "use-it-once" key to manage sessions and it worked great but we got some complaints about legitimate users getting logged out without reasons. Turns out the problem was not tentative highjacking, it was  either:

A- Users double click on links or make 2 clicks very fast. The same key is sent for the 2 clicks because the new key from the first click didn't get to the browser on time for the second one but the session on the server did trash the key for the new one. Thus, the second click causes a termination of the session. (install the LiveHttpHeaders extension on firefox and look at the headers sent when you click twice very fast, you'll see the same cookie sent on both and the new cookie getting back from the server too late).

B- For any given reason, the server experiences a slow down and the response with the new key (which has replaced the old one on the server) is not returned to the browser fast enough. The user gets tired of waiting and clicks somewhere else. He gets logged out because this second click send the old key which won't match the one you have on your server.

Our solution was to set up a grace period where the old key was still valid (the current key and the previous key were both kept at all times, we used 15 seconds as a grace period where the old key could still be used). This has the drawback of increasing the window of time for a person to highjack the session but if you tie the validity of the old key to an IP address and/or user agent string, you still get pretty good session security with very very few undesired session termination.
bmorency at jbmlogic dot com
07-Oct-2005 05:14
In response to the solution posted in the comment below, there are some practical issues with this solution that must be kept in mind and handled by your code. I developed an application using a similar "use-it-once" key to manage sessions and it worked great but we got some complaints about legitimate users getting logged out without reasons. Turns out the problem was not tentative highjacking, it was  either:

A- Users double click on links or make 2 clicks very fast. The same key is sent for the 2 clicks because the new key from the first click didn't get to the browser on time for the second one but the session on the server did trash the key for the new one. Thus, the second click causes a termination of the session. (install the LiveHttpHeaders extension on firefox and look at the headers sent when you click twice very fast, you'll see the same cookie sent on both and the new cookie getting back from the server too late).

B- For any given reason, the server experiences a slow down and the response with the new key (which has replaced the old one on the server) is not returned to the browser fast enough. The user gets tired of waiting and clicks somewhere else. He gets logged out because this second click send the old key which won't match the one you have on your server.

Our solution was to set up a grace period where the old key was still valid (the current key and the previous key were both kept at all times, we used 15 seconds as a grace period where the old key could still be used). This has the drawback of increasing the window of time for a person to highjack the session but if you tie the validity of the old key to an IP address and/or user agent string, you still get pretty good session security with very very few undesired session termination.
mega-squall at caramail dot com
23-Feb-2005 01:04
I found a solution for protecting session ID without tying them to client's IP. Each session ID gives access for only ONE querry. On the next querry, another session ID is generated and stored. If somebody hacks the cookie (or the session ID), the first one of the user and the pirate that will use the cookie will get the second disconnected, because the session ID has been used.

If the user gets disconnected, he will reconnect : as my policy is not to have more than one session ID for each user (sessions entries have a UNIQUE key on the collomn in which is stored user login), every entries for that user gets wiped, a new session ID is generated and stored on users dirve : the pirate gets disconnected. This lets the pirate usually just a few seconds to act. The slower visitors are browsing, the longer is the time pirates get for hacking. Also, if users forget to explicitly end their sessions .... some of my users set timeout longer than 20 minutes !

IMPORTANT NOTE : This disables the ability of using the back button if you send the session ID via POST or GET.
James Olsen
21-Jan-2005 08:14
Tying the session to the IP of the user is not a good idea. Some users, notably AOL users, are behind a rotating proxy which means their hits to the server will actually be coming from different IP addresses over the duration of their visit. Trying the session to the IP will not work properly for those users.
myfirstname at braincell dot cx
24-Sep-2003 08:47
[Editor's note: Wilson's comment has been deleted since it didn't contain much useful information, but this note is preserved although its reference is lost]

Just a general comment on Wilton's code snippet: It's generally considered very bad practice to store usernames and/or passwords in cookies, whether or not they're obsfucated.  Many spyware programs make a point of stealing cookie contents.

A much better solution would be to either use the PHP built in session handler or create something similar using your own cookie-based session ID.  This session ID could be tied to the source IP address or can be timed out as required but since the ID can be expired separately from the authentication criteria the authentication itself is not compromised.

Stuart Livings

<HTTP-Аутентификация в PHPSessions>
 Last updated: Mon, 14 Nov 2005