PHP: páginas seguras solo para miembros con un sistema de inicio de sesión
Desafíos con el código proporcionado
El código PHP proporcionado encuentra varios problemas que dificultan su funcionalidad:
- Recuperación de resultados de consulta: en lugar de usar $data1 = $conn->query($sql1);, el enfoque correcto es usar $data = mysqli_fetch_array($conn->query($sql1)); o $datos = $conn->query($sql1)->fetch_array(); para obtener los resultados de la consulta.
- Conexión y ejecución de la base de datos: La conexión a la base de datos debe establecerse usando $total = $data = 0; antes de ejecutar cualquier consulta.
- Sintaxis MySQLi: La consulta para insertar el token debe usar comillas invertidas () alrededor de los nombres de tablas y columnas (INSERT INTO tokens (tk, gauth) VALUES (?,? )`) en lugar de comillas simples.
- Autenticación de usuario: la lógica de autenticación debe devolver el resultado de la consulta en lugar de depender de valores booleanos ($result = $conn->query($sql3)->fetch_array();).
- Generación de tokens: El método de generación de tokens existente no es seguro ya que usa openssl_random_pseudo_bytes(). En su lugar, el código debe utilizar un generador de números aleatorios criptográficamente seguro (CSPRNG) como random_bytes().
Solución propuesta
- Simplificar las operaciones de la base de datos: Utilice una única consulta para recuperar información del usuario y comprobar las credenciales.
- Utilice declaraciones preparadas: vincule parámetros para evitar la inyección de SQL vulnerabilidades.
- Generar tokens de forma segura: emplear random_bytes() o una función similar para la generación segura de tokens.
- Almacenar datos de autenticación en la sesión: Guardar el token de autenticación en una variable de sesión en lugar de una cookie.
- Validar tokens: realiza una consulta de base de datos en la tabla de tokens para validar el token proporcionado.
Código mejorado
El siguiente código revisado aborda los problemas identificados y proporciona un sistema de inicio de sesión de página más seguro solo para miembros:
connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// Prepare statement for user authentication
$sql_auth = $conn->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$sql_auth->bind_param("ss", $_POST['uname'], $_POST['pss']);
$sql_auth->execute();
$result_auth = $sql_auth->get_result();
// Authenticate user
if ($result_auth->num_rows > 0) {
$user = $result_auth->fetch_assoc();
$correct = TRUE;
} else {
$correct = FALSE;
}
// Generate token
if ($correct === TRUE) {
$hex = bin2hex(random_bytes(3));
$_SESSION['auth'] = $hex;
$_SESSION['logstat'] = TRUE;
}
// Close connection
$conn->close();
?>