¿Cómo hacer un formulario de registro e inicio de sesión de usuario sencillo?
Lo primero que debe tener en cuenta al crear un portal de registro de usuarios es dónde y cómo va a almacenar las cuentas de usuario. Para ello vamos a utilizar la base de datos MySQL con la siguiente tabla:
CREATE TABLE IF NOT EXISTS `accounts` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`Username` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`Hash` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`UserType` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
En esta tabla vamos a almacenar el nombre de usuario y el hash de la contraseña. También tenemos una columna que nos dirá el tipo de cuenta; ya sea un usuario normal o un administrador.
Conexión a la base de datos
Obviamente necesitamos conectarnos a la base de datos e iniciar una sesión. Estos temas están fuera del alcance de esta respuesta. Vamos a usar PDO para conectarnos a nuestra base de datos que contiene nuestra nueva tabla.
<?php
session_start();
$pdo = new PDO('mysql:host=localhost;charset=utf8mb4;dbname=test', 'dbuser', 'password', [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_EMULATE_PREPARES => false
]);
Para obtener una explicación más detallada de cómo funciona PDO, consulte este artículo:https://phpdelusions.net/pdo
Función de registro
Ahora podemos crear una función simple que registrará un usuario en la base de datos. Esta función aceptará 3 parámetros:la conexión DB, el nombre de usuario y la contraseña.
Esta función creará un hash de la contraseña y luego descartará esta contraseña. Es un ejemplo simple, pero en palabras reales probablemente querrá agregar más controles y hacerlo más infalible.
function register(PDO $db, string $username, string $password)
{
if (!$username || !$password) {
throw new Exception('Username and password is required!');
}
$hash = password_hash($password, PASSWORD_DEFAULT);
$stmt = $db->prepare('INSERT INTO accounts(Username, Hash, UserType) VALUES(?,?,?)');
$stmt->execute([
$username,
$hash,
'user' // or admin
]);
}
La función de inicio de sesión
Tal como hicimos con la función de registro, crearemos una función para iniciar sesión. La función aceptará los mismos parámetros, pero en lugar de INSERT
SELECT
de la base de datos según el nombre de usuario coincidente.
Si hay un registro coincidente en la base de datos y la contraseña se verifica con el hash almacenado, almacenamos la información del usuario en una sesión. La sesión conservará esta información en el disco duro y le dará al usuario una cookie para que la utilice cuando realice futuras solicitudes. Usando esa cookie, PHP abrirá la misma sesión cada vez que se solicite la página.
function login(PDO $db, string $username, string $password)
{
if (!$username || !$password) {
throw new Exception('Username and password is required!');
}
$stmt = $db->prepare('SELECT Id, Hash, UserType FROM accounts WHERE Username=?');
$stmt->execute([ $username ]);
$user = $stmt->fetch();
if (!$user || !password_verify($password, $user['Hash'])) {
throw new Exception('Username or password incorrect!');
}
$_SESSION['loggedUserId'] = $user['Id'];
$_SESSION['UserType'] = $user['UserType'];
}
El código completo
Ahora podemos conectar todo esto y agregar algunos formularios HTML. La parte HTML está fuera del alcance, pero querrá mantenerla separada de su lógica PHP. Probablemente en un archivo separado por completo.
<?php
session_start();
$pdo = new PDO('mysql:host=localhost;charset=utf8mb4;dbname=test', 'inet', '5432', [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_EMULATE_PREPARES => false
]);
function register(PDO $db, string $username, string $password)
{
if (!$username || !$password) {
throw new Exception('Username and password is required!');
}
$hash = password_hash($password, PASSWORD_DEFAULT);
$stmt = $db->prepare('INSERT INTO accounts(Username, Hash, UserType) VALUES(?,?,?)');
$stmt->execute([
$username,
$hash,
'user' // or admin
]);
}
function login(PDO $db, string $username, string $password)
{
if (!$username || !$password) {
throw new Exception('Username and password is required!');
}
$stmt = $db->prepare('SELECT Id, Hash, UserType FROM accounts WHERE Username=?');
$stmt->execute([ $username ]);
$user = $stmt->fetch();
if (!$user || !password_verify($password, $user['Hash'])) {
throw new Exception('Username or password incorrect!');
}
$_SESSION['loggedUserId'] = $user['Id'];
$_SESSION['UserType'] = $user['UserType'];
}
if (isset($_POST['register'])) {
register($pdo, $_POST['username'], $_POST['password']);
}
if (isset($_POST['login'])) {
login($pdo, $_POST['username'], $_POST['password']);
}
if (!isset($_SESSION['loggedUserId'])):
?>
<!-- Register form -->
<form method="post">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" name="register" value="Register">
</form>
<!-- Login form -->
<form method="post">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" name="login" value="Log in">
</form>
<?php
else:
echo 'Here be something after login. You are a '.$_SESSION['UserType'];
endif;
Este es un ejemplo muy simple de cómo funciona el registro y el inicio de sesión en PHP. No recomendaría usarlo tal como está en un sitio en vivo, pero para fines de aprendizaje, debería demostrar cómo funciona esta funcionalidad.
Puede construir sobre él y hacer algo cuando el tipo de usuario sea diferente. Muestra más contenido a más usuarios privilegiados.