Contenido del curso

Lógica real de login con base de datos

Resumen

La lógica de inicio de sesión en PHP requiere validar credenciales contra una base de datos real, manejar contraseñas encriptadas y gestionar errores con mensajes claros. Aquí construimos esa pieza paso a paso, partiendo del formulario hasta la verificación final del usuario.

Esto es útil si estás desarrollando un sistema de autenticación desde cero y quieres entender cómo se conecta el formulario con el controlador, las reglas de validación y la consulta a la base de datos.

¿Cómo se conecta el formulario de login con el controlador?

El primer paso es crear la ruta que procesará los datos del formulario. Sin esa ruta, el navegador devuelve el típico mensaje de esta ruta no existe.

Para resolverlo, defines dos acciones en el controlador: una que muestra el formulario y otra que procesa el envío. La que procesa recibe el método del formulario, copia su nombre y desarrolla la lógica de validación dentro de esa acción.

¿Qué hace un controlador en un login? Recibe los datos del formulario, los valida, consulta la base de datos y decide si crea la sesión del usuario o devuelve los errores a la vista.

¿Cómo validar el email y la contraseña en el login?

La validación arranca instanciando la clase de validación con new y pasándole los datos que llegan del formulario. Aquí defines las reglas mínimas que debe cumplir cada campo antes de tocar la base de datos.

Las reglas básicas que aplicamos:

  • Email: campo requerido y con formato de correo electrónico válido.
  • Password: campo requerido.
  • Mensajes personalizados cuando falle cada regla.

Un detalle interesante apareció al probar el flujo: si escribes algo como aaa en el campo de email, el sistema lanza una excepción porque la regla de validación de correo electrónico no estaba definida. Para corregirlo, agregas un filtrado que pregunta si el valor es un correo válido y, si no lo es, muestra el mensaje Este campo debería ser un correo electrónico válido.

¿Qué pasa si la validación falla?

Cuando los datos no pasan las reglas, el controlador vuelve a renderizar la vista del formulario, pero esta vez le inyecta los errores de validación para que el usuario vea qué debe corregir. Es la misma vista de login, solo que ahora recibe un arreglo con los mensajes.

¿Cómo consultar el usuario en la base de datos con first?

Si la validación pasa, llega el momento de buscar al usuario por su email. Aquí usamos un método llamado first sobre el query builder, que devuelve el primer registro coincidente o null si no encuentra nada.

Esto contrasta con firstOrFail, que dispara una excepción si no hay resultados. Para el login conviene first, porque queremos manejar el caso usuario no encontrado con un mensaje controlado, no con un error fatal.

Durante la clase también se aprovechó para refactorizar: como firstOrFail repetía la lógica de first, ahora firstOrFail llama internamente a first y, si el resultado es nulo, falla. Menos código duplicado, misma funcionalidad.

¿Cuál es la diferencia entre first y firstOrFail? first devuelve el primer registro o null si no existe. firstOrFail hace lo mismo, pero lanza una excepción cuando no encuentra nada. Para login, usa first.

¿Por qué nunca debes guardar contraseñas sin encriptar?

Al crear la tabla de usuarios con campos name, email y password (todos varchar de 255), surge la tentación de insertar la contraseña en texto plano. Esto es un error gravísimo de seguridad.

Si alguien accede a tu base de datos, obtiene todas las contraseñas legibles. Y como muchos usuarios reutilizan la misma contraseña en distintas plataformas, el daño se multiplica más allá de tu aplicación.

Por eso la verificación dentro del controlador no compara strings directamente. Usa una función que toma la contraseña enviada por el formulario y la compara contra la versión encriptada guardada en la base de datos. Si coinciden, se crea la sesión con el ID, email y nombre del usuario, y se redirige al área autenticada.

¿Qué información se guarda en la sesión del usuario?

Una vez validadas las credenciales, la sesión almacena los datos mínimos para identificar al usuario en cada request:

  • ID del usuario.
  • Email del usuario.
  • Nombre del usuario.

Con esos tres datos puedes personalizar la experiencia y proteger rutas privadas sin tener que volver a consultar la base en cada acción.

¿Cómo manejar excepciones cuando una regla no está definida?

Un detalle elegante de la implementación: cuando se intenta usar una regla de validación que no existe, el sistema no devuelve null silenciosamente. Dispara una excepción de tipo argumento inválido con un mensaje claro indicando que esa regla no está definida.

Esto evita bugs silenciosos y obliga al desarrollador a registrar correctamente cada regla antes de usarla. Es una práctica que vale la pena replicar en cualquier capa de validación que construyas.

El reto que queda abierto: investiga cómo se crea una contraseña encriptada en PHP y comparte tu solución en los comentarios. La función password_hash y su contraparte password_verify son el punto de partida natural, y las veremos a fondo en la próxima clase.