Как узнать session id в браузере

Обновлено: 08.07.2024

Расположение временного файла можно узнать через настройки в файле php.ini, который содержит параметр session.save_path. Как правило, папка имеет имя tmp.

При открытии сессии создаётся уникальный идентификатор для этой конкретной сессии, который представляет собой случайную строку из 32 шестнадцатеричных чисел.

Файл-куки PHPSESSID автоматически сохраняется на компьютере пользователя для хранения уникальной строки идентификации сессии.

На сервере в указанном временном каталоге автоматически создаётся файл, который содержит имя уникального идентификатора с префиксом sess_.

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

Сессия заканчивается, когда пользователь закрывает браузер или покидает сайт, сервер завершает сессию по истечении заданного периода времени, обычно 30 минут.

Открытие сессии

Сессия PHP открывается с помощью функции session_start(). Эта функция сначала проверяет открытые сессии, если ни одна сессия не открыта, запускает ее. Рекомендуется поместить вызов session_start() в начало страницы. Переменные сеанса хранятся в суперглобальном ассоциативном массиве $_SESSION[]. Доступ к этим переменным можно получить во время сессии.

Код для примера. Сначала откроем сессию, затем зарегистрируем переменную с именем visit, которая увеличивается каждый раз, когда страница посещается во время сеанса. Используйте функцию isset(), чтобы проверить, установлена ли уже переменная сессии или нет.

Результат. Можете перезагрузить страницу, чтобы увидеть работу счётчика.

Вы посещали эту страницу 1 в текущей сессии.

Вы можете открыть страницу в другой вкладке, но счётчик "узнает" вас и будет увеличиваться. Вы можете закрыть все вкладки и через некоторое время открыть страницу снова. Счётчик по-прежнему работает и не сбрасывается.

Узнать идентификатор сессии можно через функцию session_id().

Интересно, что через эту же функцию с одним аргументом, который принимает идентификатор сессии, можно заменить идентификатор, который генерирует система. Но в этом случае функцию следует использовать до session_start().

Также можно сохранять не одно значение, а целый массив.

Выводим массив на страницу.

Барсик, Мурзик, Рыжик

Удаление сессии

Сессия может быть удалена с помощью функции session_destroy(). Через один вызов можно удалить все переменные сеанса. Если вы хотите удалить одну переменную сессии, вы можете использовать функцию unset(), чтобы отключить ее. Ниже приводится пример, в котором отменяется одна переменная:

Вызов, который удаляет все переменные сессии:

Включение автосессии

Вам не нужно вызывать функцию start_session(), чтобы открыть сессию, при посещении пользователем сайта, если вы установите переменную session.auto_start в файле php.ini.

Сессии без файлов cookie

Пользователь может запретить хранить файлы cookie на своем компьютере. Поэтому существует другой способ отправки идентификатора сеанса в браузер. Вы можете использовать константу SID, которая определяется, если сеанс запущен. Если клиент не отправил соответствующий сессии файл cookie, она выглядит как session_name = session_id. В противном случае она расширяется до пустой строки. Таким образом, вы можете вставлять ее в URL-адреса. В следующем примере показано как правильно регистрировать переменную и как правильно ссылаться на другую страницу с использованием SID.

Этот код сформирует ссылку, на которую можно щёлкнуть.

Сессия между страницами

Данные запоминаются, нужно только извлекать нужные значения.

Привет, Васька

Нажмите на ссылку выше, чтобы увидеть, как работает сессия между страницами.

session_create_id() используется для создания нового идентификатора текущей сессии. Возвращает идентификатор сессии, который не подвержен коллизиям.

При неактивной сессии проверка на коллизии не осуществляется.

Идентификатор сессии создаётся в соответствии с настройками php.ini.

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

Список параметров

Если указан параметр prefix , то новый идентификатор сессии будет с префиксом prefix . Не все символы возможно использовать в идентификаторе сессии. Допускается использовать только символы из диапазона: a-z A-Z 0-9 , (запятая) и - (минус) .

Возвращаемые значения

session_create_id() возвращает новый, не подверженный коллизиям, идентификатор текущей сессии. Если используется при неактивной сессии, проверка на коллизии пропускается. В случае неудачи возвращается false .

Примеры

<?php
// Функция My session start с управлением на основе временных меток
function my_session_start () session_start ();
// Не разрешать использование слишком старых идентификаторов сессии
if (!empty( $_SESSION [ 'deleted_time' ]) && $_SESSION [ 'deleted_time' ] < time () - 180 ) session_destroy ();
session_start ();
>
>

// Далее основной код программы
?>

Смотрите также

  • session_regenerate_id() - Генерирует и обновляет идентификатор текущей сессии
  • session_start() - Стартует новую сессию, либо возобновляет существующую
  • SessionHandler::create_sid() - Возвращает новый идентификатор сессии

User Contributed Notes 2 notes

This function is very hard to replicate precisely in userland code, because if a session is already started, it will attempt to detect collisions using the new "validate_sid" session handler callback, which did not exist in earlier PHP versions.

If the handler you are using implements the "create_sid" callback, collisions may be detected there. This is called when you use session_regenerate_id(), so you could use that to create a new session, note its ID, then switch back to the old session ID. If no session is started, or the current handler doesn't implement "create_sid" and "validate_sid", neither this function nor session_regenerate_id() will guarantee collision resistance anyway.

If you have a suitable definition of random_bytes (a library is available to provide this for versions right back to PHP 5.3), you can use the following to generate a session ID in the same format PHP 7.1 would use. $bits_per_character should be 4, 5, or 6, corresponding to the values of the session.hash_bits_per_character / session.sid_bits_per_character ini setting. You will then need to detect collisions manually, e.g. by opening the session and confirming that $_SESSION is empty.

<?php
function session_create_random_id ( $desired_output_length , $bits_per_character )
$bytes_needed = ceil ( $desired_output_length * $bits_per_character / 8 );
$random_input_bytes = random_bytes ( $bytes_needed );

// The below is translated from function bin_to_readable in the PHP source (ext/session/session.c)
static $hexconvtab = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,-' ;

$p = 0 ;
$q = strlen ( $random_input_bytes );
$w = 0 ;
$have = 0 ;

$mask = ( 1 << $bits_per_character ) - 1 ;

$chars_remaining = $desired_output_length ;
while ( $chars_remaining --) if ( $have < $bits_per_character ) if ( $p < $q ) $byte = ord ( $random_input_bytes [ $p ++] );
$w |= ( $byte << $have );
$have += 8 ;
> else // Should never happen. Input must be large enough.
break;
>
>

// consume $bits_per_character bits
$out .= $hexconvtab [ $w & $mask ];
$w >>= $bits_per_character ;
$have -= $bits_per_character ;
>

session_id() используется для получения или установки идентификатора текущей сессии.

Константа SID также может быть использована для получения текущего имени и идентификатора сессии в виде строки, подходящей для добавления в URL-адреса. Смотрите также Работа с сессиями.

Список параметров

Если указан параметр id и он не равен null , то он заменит идентификатор текущий сессии. Для этого session_id() следует вызывать до session_start() . В зависимости от обработчика сессии, не все символы возможно использовать в идентификаторе сессии. Например, файловый обработчик сессии поддерживает только символы из диапазона a-z A-Z 0-9 , (запятая) и - (минус) !

Замечание: При использовании сессионных cookie, указание id для session_id() приводит к тому, что при вызове session_start() всегда будут отправлены новые cookie, независимо от того, совпадает ли идентификатор текущей сессии с вновь установленным.

Возвращаемые значения

session_id() возвращает идентификатор текущей сессии или пустую строку ( "" ), если нет текущей сессии (идентификатор текущей сессии не существует). В случае неудачи возвращает false .

Список изменений

Версия Описание
8.0.0 id теперь может быть null .

Смотрите также

  • session_regenerate_id() - Генерирует и обновляет идентификатор текущей сессии
  • session_start() - Стартует новую сессию, либо возобновляет существующую
  • session_set_save_handler() - Устанавливает пользовательские обработчики хранения сессии
  • session.save_handler

User Contributed Notes 22 notes

It may be good to note that PHP does not allow arbitrary session ids. The session id validation in PHP source is defined in ext/session/session.c in the function php_session_valid_key:

To put it short, a valid session id may consists of digits, letters A to Z (both upper and lower case), comma and dash. Described as a character class, it would be [-,a-zA-Z0-9]. A valid session id may have the length between 1 and 128 characters. To validate session ids, the easiest way to do it use a function like:

function session_valid_id ( $session_id )
return preg_match ( '/^[-,a-zA-Z0-9]$/' , $session_id ) > 0 ;
>

?>

session_id() itself will happily accept invalid session ids, but if you try to start a session using an invalid id, you will get the following error:

Warning: session_start(): The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,'

I was perplexed by inconsistent results with the session ID depending on whether I retrieve it using SID, COOKIE, or session_id(). I have found that session_id() is the most reliable method, whereas SID and COOKIE["PHPSESSIONID"] are sometimes undefined.

I used this simple script to quickly test the problem on my servers:

<?php
$a = session_id ();
if(empty( $a )) session_start ();
echo "SID: " . SID . "<br>session_id(): " . session_id (). "<br>COOKIE: " . $_COOKIE [ "PHPSESSID" ];
?>

Regardless of browser I see the COOKIE undefined on the first load and the other two defined, then SID is empty on subsequent reloads and COOKIE is defined, but session_id() is always defined.

If I insert the session_regenerate_id() method that jeff_zamrzla gives below the refresh the page, I get a new session_id() but the COOKIE value is initially the prior session_id() until I hit refresh a second time. So again, session_id() proves to be the most reliable method.

It's probably not a bug since I found the behaviour to be consistent in PHP versions 5.2.14, 5.3.3 and 5.3.4, but I can't figure what I'm missing and hopefully this will help others who run into this.

session_id() URL-decodes the session value. For example let's say we use setcookie() to push a cookie down to a web browser. When the browser makes the next page request the browser sends the cookie back up to us with headers like this: Cookie: PHPSESSID=enGHumY%2C-2De-F-TDzNHVmE%2ChY5;

If we use session_id() to read the cookie it will output a value of this: enGHumY,-2De-F-TDzNHVmE,hY5

The two values don't match! Use either setrawcookie() or URL encode if you wish to match the original value.

This can looks obvious, but as me, you can spend some hours to make a simple session work between different browsers and devices. These are the basics for me, but you can build upon.

<?php
if( $_GET ) //defining the session_id() before session_start() is the secret
session_id ( $_GET [ 'session_id' ]);
session_start ();
echo "Data: " . $_SESSION [ 'theVar' ];
//use your data before below commands
session_destroy ();
session_commit ();
>else //common session statement goes here
session_start ();
$session_id = session_id ();
$_SESSION [ 'theVar' ] = "theData" ;
echo "your.php?session_id keyword">. $session_id ;
>
?>

IMPORTANT NOTE:
If you assign a specific session ID to a user in your applet, then do not run the following code either while logout,
session_regenerate_id(TRUE);
USE:
session_regenerate_id(); instead.
OTHERWISE, setting the session id will no longer works for that user.

About the note from Cybertinus :

The following test doesn't work, the code following is always executed :

<?php
if(! session_id ())
<
// Always executed even if there's already an opened session
>

session_id () returns an empty string if there is no current session , so to test if a session already exists , it 's better to write this :
if(session_id() == "")
<
session_start();
>
else
<
// Anything you want
>
?>

Regarding Colin's comment, note that setting hash_bits_per_character to 5 results in characters ranging from 0-9 and a-v. Most attackers would be wise enough to realize what was going on when they saw a letter in g-v. The probability of not seeing a letter in g-v is somewhere around 2^-32. Rewriting URL's is not suggested for obvious security issues. Please be careful with register_globals when using sessions! Check that all information you recieve from a user is valid before accepting it!

Note that Firefox and Mozilla use the same process for launching new windows or tabs, they will pick up the same session id as the previous windows until the parent process dies or is closed. This may cause undesired results if the session id is stored in a db and checked, a solution is to check at the new entry point (new tab or window if the user went back to the index page) for an existing session. If a session id exists and a new one is required use something like:

<?php
$ses_id = session_id ();
$bsid_exists = false ;
$bsid_exists = check_session_id_from_db ( $ses_id );
if ( $bsid_exists ) <
//This is a reentry and the session already exists
// create a new session ID and start a new
session_regenerate_id ();
$ses_id = session_id ();
>
?>

Length of PHPSESSID appears to be 32 characters by default.

Gosh, took a LOOONG time to figure this one out! If you have suhosin built into your PHP and can't get sessions to work after changing the session id through session_id(), try turning off suhosin's session encryption option in php.ini with:

The call session_id(null) and session_id() provides not the same result. It is imperative to pass no parameters to get correct results.

In response to simon at quo dot com dot au:

Starting with PHP 5.0, you can change the hash function used (by setting "session.hash_function" to whatever function you want to use in php.ini).
You may for example set it to 1 to switch to SHA-1 which produces 160 bits (20 bytes) long hashes.

Please also note that another setting was introduced in PHP 5 (session.hash_bits_per_character) which sort of "compresses" the hash. Thus, resulting in what seems to be a shorter hash.
This feature helps you improve your application's security by producing IDs that are harder to prodict for a malicious attacker.

The higher you set session.hash_bits_per_character the shorter your session_id will become by using more bits per character. The possible values are 4, 5, or 6.

When using sha-1 for hashing (by setting ini_set('session.hash_function', 1) the following session string lengths are produced by the three session.hash_bits_per_character settings:

4 - 40 character string
5 - 32 character string
6 - 27 character string

It would seem desirable to use sha-l with 5 bits_per_character because this will emulate a standard 32 character md5 string and make a would-be attacker think that is what you're hashing with.

I had a lot of trouble with session_regenerate_id() as it did not regenerate. Session_id() stayed the same no matter what (unless closing the window). I wanted to have different sid and empty vars for each session/page meeting a condition for security reasons. Finally, this worked:

<?php
$a = session_id ();
if ( $a == '' ) session_start ();
if ( . add check if you want to regenerate and destroy vars on some condition only [ recommended :)]. )
< session_unset (); //destroys variables
session_destroy () //destroys session;
>

$a = session_id ();
if ( $a == '' ) session_start ();
if (!isset( $_SESSION [ 'safety' ]))
session_regenerate_id ( true );
$_SESSION [ 'safety' ] = true ;
>
$_SESSION [ 'sessionid' ] = session_id ();
?>

Now you get different sid and session variables empty for each session_start if condition is met (i.e. user hits refresh on user/password form, which I needed badly :). Hope this helps someone out there.
Env: localhost
Note: condition is mandatory, otherwise it destroys on each load.

The documentation for session_id is incomplete when it says:
"For example, the file session handler only allows characters in the range a-z, A-Z and 0-9!".

It is untrue when changing the default for the session.hash_bits_per_character as Colin said. session_id may therefore contain "-" and ",".

In php version 5.3.2 in my case each time a new session-id was generated after session_start() but all was working before correctly in previous versions. So I lost data from my current session (wrong session-id). There was always a $_POST or $_GET or $_COOKIE available with the session-name and session-id, so session_start() was taken this automatically. Now I have to execute session_id(..old id ..) before session_start() and a session is started for the same id. you can also add the iframe tag:
ini_set("url_rewriter.tags", "a=href,area=href,frame=src,iframe=src,input=src,form=fakeentry");

Get a shared session.

Sometimes is good can interchange messages and vars between one session and another, but PHP dont support this. I create this script that allows with session_id() change from current session to shared session (this is, info with scope to all sessions) for read and write info and back in to user session. The code:

<?php
ini_set ( 'display_errors' , 1 );
error_reporting ( E_ALL );

function get_global ( $key ) //Get current session
if( session_status ()!= PHP_SESSION_ACTIVE ) session_start ();
$current_id = session_id ();
session_write_close ();
//Set a global session with session_id=1
session_id ( 1 );
session_start ();
//Get superglobal value
$value = null ;
if(isset( $_SESSION [ $key ])) $value = $_SESSION [ $key ];
session_write_close ();
//Set the before session
session_id ( $current_id );
session_start ();
return $value ;
>

function set_global ( $key , $value ) //Get current session
if( session_status ()!= PHP_SESSION_ACTIVE ) session_start ();
$current_id = session_id ();
session_write_close ();
//Set a global session with session_id=1
session_id ( 1 );
session_start ();
//Set superglobal value
$_SESSION [ $key ]= $value ;
session_write_close ();
//Set the before session
session_id ( $current_id );
session_start ();
>
//Example
//Begin my session normally
session_start ();
if(empty( $_SESSION [ 'count' ])) $_SESSION [ 'count' ]= 0 ;
$_SESSION [ 'color' ]= "rgb(" . rand ( 0 , 255 ). "," . rand ( 0 , 255 ). "," . rand ( 0 , 255 ). ")" ;
>
$_SESSION [ 'count' ]++;
$id = session_id ();
//Get the superglobal
$test = get_global ( "test" );
//Set the superglobal test with empty array if this dont set
if( $test == null ) $test =array();
//Get the superglobal
$test = get_global ( "test" );
//Set values for each reload page and save the session_id that create it
$test []= "<span style='color:" . $_SESSION [ 'color' ]. "'>Value: " . rand ( 0 , 100 ). " SessionID: $id </span><br>" ;
//Save the superglobal
set_global ( "test" , $test );
//Show the superglobal
foreach( $test as $t ) echo $t ;
>
echo "<b>Reloads keyword">. $_SESSION [ 'count' ]. ", <span style='color:" . $_SESSION [ 'color' ]. "'>This my color</span></b>" ;

Try this code snippet, from a book by a security expert who says this is more secure to place on every page:

<?php
session_start ();
$_SESSION [ 'name' ] = "YourSession" ;

if (!isset( $_SESSION [ 'initiated' ]))
<
session_regenerate_id ();
$_SESSION [ 'initiated' ] = true ;
>
?>

session_regenerate_id() заменяет идентификатор текущей сессии вновь сгенерированным, при этом сохраняет информацию о текущей сессии.

Текущая реализация session_regenerate_id() плохо работает с сетями с нестабильным соединением, такими как мобильные и WiFi-сети. Таким образом, есть вероятность потерять сессию из-за вызова session_regenerate_id() .

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

Список параметров

Определяет, удалять ли старый связанный файл с сессией или нет. Не следует удалять старую сессию, если требуется избегать состояния гонки из-за удаления или обнаруживать/избегать атак при перехвате сессии.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

<?php
// ЗАМЕЧАНИЕ: Это не полностью работающий код, а только пример!

// Проверяем временную метку удаления
if (isset( $_SESSION [ 'destroyed' ])
&& $_SESSION [ 'destroyed' ] < time () - 300 ) // Обычно это не должно происходить. Это может быть атакой или результатом нестабильной сети.
// Удаляем все статусы аутентификации пользователей этой сессии.
remove_all_authentication_flag_from_active_sessions ( $_SESSION [ 'userid' ]);
throw(new DestroyedSessionAccessException );
>

// Устанавливаем временную метку удаления
$_SESSION [ 'destroyed' ] = time (); // session_regenerate_id() сохраняет данные старой сессии

// Просто вызов session_regenerate_id() может привести к потере сессии и т.д.
// Смотрите следующий пример.
session_regenerate_id ();

// Новой сессии не требуется временная метка удаления.
unset( $_SESSION [ 'destroyed' ]);

echo "Старая сессия: $old_sessionid <br />" ;
echo "Новая сессия: $new_sessionid <br />" ;

Текущий модуль сессии не работает хорошо с сетями с нестабильным соединением. Вы должны управлять идентификатором сессии, чтобы избежать потери сессии в результате вызова session_regenerate_id() .

<?php
// ЗАМЕЧАНИЕ: Это не полностью работающий код, а только пример!
// my_session_start() и my_session_regenerate_id() избегают потери
// сессии из-за нестабильной сети. В дополнение, данный код может предотвращать
// использование украденных сессий злоумышленниками.

function my_session_start () session_start ();
if (isset( $_SESSION [ 'destroyed' ])) if ( $_SESSION [ 'destroyed' ] < time ()- 300 ) // Обычно это не должно происходить. Это может быть атакой или результатом нестабильной сети.
// Удаляем все статусы аутентификации пользователей этой сессии.
remove_all_authentication_flag_from_active_sessions ( $_SESSION [ 'userid' ]);
throw(new DestroyedSessionAccessException );
>
if (isset( $_SESSION [ 'new_session_id' ])) // Срок действия ещё не полностью истёк. Cookie могли быть потеряны из-за нестабильной сети.
// Заново пытаемся установить правильный cookie идентификатора сессиии.
// ЗАМЕЧАНИЕ: Не пытайтесь заново установить идентификатор сессии если, вы предпочитаете
// удалить флаг аутентификации.
session_commit ();
session_id ( $_SESSION [ 'new_session_id' ]);
// Новый идентификатор сессии должен существовать.
session_start ();
return;
>
>
>

function my_session_regenerate_id () // Новый идентификатор сессии необходим для установки правильного идентификатора сессии,
// когда идентификатор сессии не был установлен из-за нестабильной сети.
$new_session_id = session_create_id ();
$_SESSION [ 'new_session_id' ] = $new_session_id ;

// Устанавливаем временную метку удаления.
$_SESSION [ 'destroyed' ] = time ();

// Записываем и закрываем текущую сессию.
session_commit ();

// Новой сессии не нужно это.
unset( $_SESSION [ 'destroyed' ]);
unset( $_SESSION [ 'new_session_id' ]);
>
?>

Читайте также: