PHP 8.1.30 Released!

session_create_id

(PHP 7 >= 7.1.0, PHP 8)

session_create_idCrear un nuevo ID de sesión

Descripción

session_create_id(string $prefix = ?): string

session_create_id() se emplea para crear nuevos ID de sesión para la sesión actual. Devuelve los ID de sesión libres de colisiones.

Si la sesión no está activa, la comprobación de colisiones se omite.

El ID de sesión se crea de acuerdo a los ajustes de php.ini.

Es importante utilizar el mismo ID de usuario del servidor web para las tareas de recolección de basura. De lo contrario, se podrían tener problemas de permisos especialmente con manejadores de guardado de ficheros.

Parámetros

prefix

Si se especifica prefix, el nuevo ID de sesión se prefijará con prefix. No todos los caracteres están permitidos con el ID de sesión. Están permitidos los caracteres del rango a-z A-Z 0-9 , (coma) y - (menos).

Valores devueltos

session_create_id() devuelve el nuevo ID de sesión libre de colisiones para la sesión actual. Si se emplea sin una sesión activa, se omite la comprobación de colisiones.

Ejemplos

Ejemplo #1 Ejemplo de session_create_id() con session_regenerate_id()

<?php
// Mi función de inicio de sesión admite la gestión de marcas de tiempo
function mi_inicio_de_sesión() {
session_start();
// No permitir usar un ID de sesión demasiado antiguo
if (!empty($_SESSION['deleted_time']) && $_SESSION['deleted_time'] < time() - 180) {
session_destroy();
session_start();
}
}

// Mi función de regeneración de ID de sesión
function mi_regeneración_de_id_de_sesión() {
// Llamar a session_create_id() mientras la sesión está activa para
// asegurarse de que no haya colisiones.
if (session_status() != PHP_SESSION_ACTIVE) {
session_start();
}
// ADVERTENCIA: ¡No utilizar nunca cadenas confidenciales para el prefijo!
$nuevo_id = session_create_id('miprefijo-');
// Establecer la marca de tiempo de borrado. Los datos de la sesión no deben eliminarse inmediatamente.
$_SESSION['deleted_time'] = time();
// Finalizar la sesión
session_commit();
// Asegurarse de aceptar ID de sesiones definidas por el usuario
// NOTA: Se debe habilitar 'use_strict_mode' para operaciones normales.
ini_set('session.use_strict_mode', 0);
// Establecer el nuevo ID de sesión personalizado
session_id($nuevo_id);
// Empezar la sesión con el ID de sesión personalizado
session_start();
}

// Asegurarse de que 'use_strict_mode' está habilitado.
// 'use_strict_mode' es obligatorio por razones de seguridad.
ini_set('session.use_strict_mode', 1);
mi_inicio_de_sesión();

// EL ID de sesión debe regenerarse cuando
// - El usuario inicia la sesión
// - El usuario cierra la sesión
// - Ha transcurrido un cierto perido de tiempo
mi_regeneración_de_id_de_sesión();

// Escribir código útil
?>

Ver también

add a note

User Contributed Notes 1 note

up
4
rowan dot collins at gmail dot com
6 years ago
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,-';

$out = '';

$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;
}

return
$out;
}
?>
To Top