Desarrollador de aplicaciones web y de escritorio, amante de la tecnología y autodidacta, me gusta conocer otras tecnologías, escribir artículos para compartir en la web y para estar al tanto en los nuevos paradigmas, respeto las políticas de software privativo y libre, ya que estas políticas son las normas que permite el desarrollo tecnológico social de la humanidad. filvovmax@gmail.com -- info@gitmedio.com
código en php y mysql sistema de autenticación
En este articulo, se muestra el ejemplo de código en php y mysql sistema de autenticación de usuarios, en otras palabras con este tipo sistema se podrá autorizar el acceso restringido a la pagina privada, donde cada uno de los usuarios autorizados podrá tener datos como: una contraseña un nombre de usuario y entro otros.
En el anterior articulo se había mostrado un ejemplo de maqueado de un formulario de login en HTML5 Y CSS, lo que se hará en los siguientes ejemplos de códigos es implementar la validación para el acceso a la pagina restringida para las personas autorizadas. Básicamente estaremos utilizando JavaScritp, PHP y MySQL.
Para que accedan los usuarios autorizados a la pagina restringida, para eso debemos tener sus datos como: un identificador numérico, nombre, apellido, correo electrónico y una clave. Cuyos datos se deben plasmar en un estructura de base datos es decir se creará un tabla que contendrá por lo menos 5 campos.
He aquí el ejemplo del diseño y estructura de la tabla.
A continuación en el siguiente ejemplo, se realiza a crear la base de datos y la tabla con sus respectivos campos y tipo de datos, con el código SQL.
CREATE DATABASE logeo;
CREATE TABLE `tb_login` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`Nombre` varchar(70),
`Apellido` varchar(80),
`Correo` varchar(40),
`Contra` varchar(255),
`CodRecup` varchar(255),
PRIMARY KEY (`id`)
);
En el siguiente ejemplo, lo que se hará es codificar el funcionamiento de logueo (script php), es decir cuando llene los datos el usuario en los cajas de texto, determine cuyos datos si son válidos para que ingrese a la página privada.
El primer escript php que ay que codificar es muy sencillo, lo cual debe permitir la configuración de datos para la conexión a la base de datos. El script se realiza con orientación a objetos, donde básicamente tiene 4 campos privados asignados con datos, y cuatro métodos que devolverán datos para acceder al servidor de base datos MySQL.
Archivo: config.php
<?php
/**
* Autor: Rodrigo Chambi Q.
* Mail: filvovmax@gmail.com
* web: www.gitmedio.com
*/
/**
* Clase para realizar conexión
* a la BD, solo cambiar datos de los
* campos.
*/
class Datos_conexion {
private $host_="localhost";
private $usuario_="root";
private $pasword_="";
private $Db_="logeo";
/**
* Devuelve el nombre de hsot
* @return [type] [string]
*/
public function host(){
return $this->host_;
}
/**
* Devuelve el nombre de usuario
* @return [type] [string]
*/
public function usuario(){
return $this->usuario_;
}
/**
* Devuelve la contraseña de acceso
* @return [type] [string]
*/
public function pasword(){
return $this->pasword_;
}
/**
* Devuelve nombre de la base de datos
* @return [type] [string]
*/
public function DB(){
return $this->Db_;
}
}
Segundo script php, aquí es donde se realiza la validación de los datos de usuario cuando intente acceder, se crea un clase llamado Login donde encapsula cuatro campos privados, y cuatro métodos mas un constructor tal como se ve en el siguiente ejemplo.
Archivo: determ.php
<?php
/**
* Autor: Rodrigo Chambi Q.
* Mail: filvovmax@gmail.com
* web: www.gitmedio.com
*/
session_start();
//importando datos para
//conectarse
require_once 'PasswordHash.Class.php';
require_once 'config.php';
/**
* clase para hacer login
* a la seccionde administracion
*/
class Login{
//campos que alamcenan los valores
private $Mail_ ="";
private $Contrasena_ ="";
private $Mensaje ="";
private $Nombre_usr ="";
/**
* [constructor recibe argumentos]
* @param [type] $Mail [ingresar correo]
* @param [type] $Pasword [Ingresar contraseña]
*/
function __construct($Mail,$Pasword){
$this->Mail_=$Mail;
$this->Contrasena_=$Pasword;
}
/**
* [Metdo devuelve true o false para ingresar
* a la sección de pagina restringida
* ]
*/
public function Ingresar(){
//determinamos cada uno de los
//metodos devueltos
if($this->ValidarUser()==false){
$this->Mensaje=$this->Mensaje;
}else{
if($this->Pasword_usr()==false){
$this->Mensaje=$this->Mensaje;
}else{
//si el logeo es correcto hace la redireccion
if (!empty($_SERVER['HTTPS']) && ('on' == $_SERVER['HTTPS'])) {
$uri = 'https://';
}else{
$uri = 'http://';
}
$uri .= $_SERVER['HTTP_HOST'];
//Aqui modificar si el pag de aministracion esta
//en un subdirectorio
// "<script type=\"text/javascript\">
// window.location=\"".$uri."/wp-admin/admin.php\";
// </script>";
echo "<script type=\"text/javascript\">
window.location=\"".$uri."/admin.php\";
</script>";
}
}
}
/**
* Validamos la entrada de correo
* electrónico
* @param [String mail]
*/
private function ValidarUser(){
$retornar=false;
$mailfilter =filter_var($this->Mail_,FILTER_VALIDATE_EMAIL);//filtramos el correo
//Validamos el formato de correo electronico utilizando expresiones regulares
if(preg_match("/[a-zAZ0-9\_\-]+\@[a-zA-Z0-9]+\.[a-zA-Z0-9]/", $mailfilter )==true){
//intanciando de las clases
$confi=new Datos_conexion();
$mysql=new mysqli($confi->host(),$confi->usuario(),$confi->pasword(),$confi->DB());
//Determinamos si la conexion a la bd es correcto.
if(!$mysql){
$this->Mensaje='<div class="alert alert-danger alert-dismissible fade in" role="alert"> <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button> <strong> Error!</strong> Servidor de datos no econtrado, vuelva a intentar mas tarde. </div>';
}else{
//consulta SQL para vereficar si existe tal correo del
//usario que introdujo
$query = "SELECT
tb_login.Correo
FROM
tb_login
WHERE tb_login.Correo='".$mailfilter."';";
$respuesta = $mysql->query($query);
//Aquí determinamos con la instrucción if
//la consulta generada, si mayor a cero
//retornamos el valor verdadero
//por el contrario mensaje de error
if($respuesta->num_rows>0){
//asignamos el mail sanitizado al campo Mail_
$this->Mail_=$mailfilter;
$retornar=true;// se retorna un valor verdadero
}else {
$this->Mensaje='<div class="alert alert-danger alert-dismissible fade in" role="alert"> <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button> <strong> Error!</strong> EL correo no existe, usted no podra ingresar. </div>';
}
}
}else{
//Se muestra al usuario el mensaje de error sobre
//el formato de correo
$this->Mensaje='<div class="alert alert-danger alert-dismissible fade in" role="alert"> <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button> <strong> Error!</strong> El correo que ingresaste no tiene formato correcto. </div>';
}
return $retornar;
}
/**
* Método para determinar
* la existencia de la contraseña y verificación
* @param [type] $pasword [ingresar contraseña]
*/
private function Pasword_usr(){
$retornar = false;
//saneamos la entrada de los caracteres
$contra = filter_var($this->Contrasena_, FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES | FILTER_FLAG_ENCODE_AMP);
if($contra==""){
//si es que no existen ningún
//contraseña mostramos el mensaje de error
$this->Mensaje='<div class="alert alert-danger alert-dismissible fade in" role="alert"> <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button> <strong> Error!</strong> Escriba su contraseña. </div>';
}else{
//Realizamos la consulta sql a la bd
//y verificamos la contraseña
$Contrasena = new PasswordHash(8, FALSE);
$query="SELECT
tb_login.Correo,
tb_login.Contra,
tb_login.Nombre,
tb_login.id
FROM
tb_login
WHERE tb_login.Correo='".$this->Mail_."'";
//instancia de las clases
$confi=new Datos_conexion();
$mysql=new mysqli($confi->host(),$confi->usuario(),$confi->pasword(),$confi->DB());
$respuesta = $mysql->query($query);//se ejecuta la consulta SQL
//Determinamos con la instrccion if
//si es que la consulta nos devuelve un valor
//mayor a cero
if($respuesta->num_rows>0){
//se obtiene el arreglo de la base de datos
$row = $respuesta->fetch_row();
//Recuperacion el Hash de la BD
$Hashing = $row[1];
//Realizamos el comparación del paswrod con la instrucción if
if($Contrasena->CheckPassword($contra, $Hashing)){
//Recuperamos el Id del usuario
$idsur =$row[3];
//Recuperamos el nombre de usuario para imprimir
$this->Nombre_usr = $row[2];
//Recuperando el IP del usuario a través del método IPuser()
$IpUsr = $this->IPuser();
//Recuperando la hora en el que ingreso
$hora = time();
//Recuperamos los dados para incriptar
$Clave = $Contrasena->HashPassword($idsur.$IpUsr.$this->Nombre_usr.$hora);
//Registrando a la varaible global datos en un arreglo para iniciar session
$_SESSION['INGRESO'] = array(
"Id" =>$idsur,
"Ip" =>$IpUsr,
"Clave" =>$Clave,
"Nombre"=>$this->Nombre_usr,
"hora" =>$hora);
//Asignamos el valor verdadero para retornarlo
$retornar = true;
}else {
$this->Mensaje ='<div class="alert alert-danger alert-dismissible fade in" role="alert"> <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button> <strong> Error!</strong> Contraseña incorrecto escriba nuevamente. </div>';
$retornar =false; //El paswor ingresado no es correcto
}
}
}
return $retornar; //Retornamos el valor true o false
}
/**
* Retorna el IP de usuario
* @return [string] [devuel la io del usuario]
*/
private function IPuser() {
$returnar ="";
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
$returnar=$_SERVER['HTTP_X_FORWARDED_FOR'];}
if (!empty($_SERVER['HTTP_CLIENT_IP'])){
$returnar=$_SERVER['HTTP_CLIENT_IP'];}
if(!empty($_SERVER['REMOTE_ADDR'])){
$returnar=$_SERVER['REMOTE_ADDR'];}
return $returnar;
}
/**
* Devuelve el mensaje generado
* para mostrar al usuario
*/
public function MostrarMsg(){
return $this->Mensaje;
}
}
?>
El constructor de la clase tiene dos argumentos que se encarga de recibir datos como correo y contraseña, cuyos datos son almacenados en los campos.
EL método Ingresar(), este se encarga de determinar los valores devueltos de los otros dos métodos ValidarUser() y Pasword_usr(), si los dos métodos devuelven valores verdaderos redirige a la pagina restringida.
Método ValidarUser(), básicamente este método valida la entrada de correo y hace una consulta a la base de datos, si el correo existe devuelve un valor verdadero, caso contrario un valor falso.
Método Pasword_usr(), este método valida la contraseña , y lo que hace es realizar la consulta a la base de datos, si la consulta devuelve un valor mayor a cero, se compara la contraseña con el método CheckPassword de la clase PHPass y así podrá devolver un valor verdadero o falso. Si la contraseña es correcto se recupera los datos del usario y esta es asignado al variable gobal $_SESSION con el tipo de dato array.
Método IPuser(), este método lo que hará es devolver la IP del usuario.
Método MostrarMsg(), devuelve un string HTML para mostrar mensaje al usuario es decir a lado del cliente.
El usuario que acceda a la pagina restringida, obviamente en el metodo Ingresar() debería haber cumplido al aplicar con las instruciones if con valores verdaderos, donde se redirigi a la pagina restringida, en el cuyo pagina se termina el inicio de session al acceder a la variable global $_SESSION, caso contrario es redirigido a la pagina de incicio, donde se encuentra el formulario de login. En el siguiente ejemplo de codigo se muestra el script de la pagina restringida.
Archivo: admin.php
<?php
session_start();
require_once 'PasswordHash.Class.php';
//Para redireccionar si es que no se cumple
//el logeo
if (!empty($_SERVER['HTTPS']) && ('on' == $_SERVER['HTTPS'])) {
$uri = 'https://';
}else{
$uri = 'http://';
}
$uri .= $_SERVER['HTTP_HOST'];
if(!empty($_SESSION['INGRESO'])){
if(count($_SESSION['INGRESO'])>0){
//Recuperamos datos del arreglo
$IDusr =$_SESSION['INGRESO']["Id"];
$Ipusr =$_SESSION['INGRESO']["Ip"];
$Claveusr =$_SESSION['INGRESO']["Clave"];
$Nombreusr =$_SESSION['INGRESO']["Nombre"];
$HorSesion =$_SESSION['INGRESO']["hora"];
//instancia de la clase PHpass
$Contrasena = new PasswordHash(8, FALSE);
//se uni los datos para verificar
$Ccontrase=$IDusr.$Ipusr.$Nombreusr.$HorSesion;
if($Contrasena->CheckPassword($Ccontrase, $Claveusr)){
?>
<!-- ingrese aquifunciones y diseño de tu pagina de seccion de administracion-->
<!DOCTYPE html>
<html>
<head>
<title>Seccion de administracion</title>
</head>
<body>
<ul>
<li><strong>Usuario:</strong> <?php echo $Nombreusr; ?></li>
<li><a href="salir.php">Salir</a></li>
</ul>
</body>
</html>
<?php
}else{
//Se redicciona si es que no se cumple
//Modificar como en la siguiete linea de codigo
//si es que esta en un subdirectorio
// header("location: ".$uri."/wp-admin");
header("location: ".$uri);
}
}else{
//Se redicciona si es que no se cumple
//Modificar como en la siguiete linea de codigo
//si es que esta en un subdirectorio
// header("location: ".$uri."/wp-admin");
header("location: ".$uri);
}
}else{
//redirecionado si no existe la variable global
//Modificar como en la siguiete linea de codigo
//si es que esta en un subdirectorio
// header("location: ".$uri."/wp-admin");
header("location: ".$uri);
}
/**
* Returna el IP de usuario
* @return [string] [devuel la io del usuario]
*/
function IPuser() {
$returnar ="";
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
$returnar=$_SERVER['HTTP_X_FORWARDED_FOR'];}
if (!empty($_SERVER['HTTP_CLIENT_IP'])){
$returnar=$_SERVER['HTTP_CLIENT_IP'];}
if(!empty($_SERVER['REMOTE_ADDR'])){
$returnar=$_SERVER['REMOTE_ADDR'];}
return $returnar;
}
?>
Si ingresa un usuario a la pagina restringida tambien tiene que tener una opcion para deslogearse o cerrar sesion, basicamente se puede realizar con un sencillo escript php, tal como se ve en el siguiente ejemplo.
Archivo: salir.php
<?php
session_start();
//se destruí la variable global
unset($_SESSION['INGRESO']);
if (!empty($_SERVER['HTTPS']) && ('on' == $_SERVER['HTTPS'])) {
$uri = 'https://';
}else{
$uri = 'http://';
}
$uri .= $_SERVER['HTTP_HOST'];
//Se redicciona una vez borrado la variable global
//Modificar como en la siguiente linea de codigo
//si es que esta en un subdirectorio
// header("location: ".$uri."/wp-admin");
header("location: ".$uri);
?>
Espero que hayan entendido sobre la breve explicación, continuación cuyo clase llamado Login se implementara en el archivo index.php es decir donde se muestra el diseño del formulario de login. El procedimiento de implementación es muy sencillo, que a continuación se muestra en el siguiente ejemplo.
Archivo: index.php
<?php
/**
* Autor: Rodrigo Chambi Q.
* Mail: filvovmax@gmail.com
* web: www.gitmedio.com
*/
require_once 'determ.php';
?>
<!DOCTYPE html>
<html>
<head>
<title>sistema de login</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<!-- vinculo a bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Temas-->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="estilo.css">
</head>
<body>
<div id="Contenedor">
<div class="Icon"><span class="glyphicon glyphicon-user"></span></div>
<?php
//Datos para ingresar
//usuario: marcos@gmail.com
//Contraseña: test12345
//Se la realiza la validacion de las variable globales
if(!empty($_POST['correo']) && !empty($_POST['contra'])){
$iniciar=new Login($_POST['correo'],$_POST['contra']);
$iniciar->Ingresar();
//Muestra el mesaje de error al usuario
echo $iniciar->MostrarMsg();
}
?>
<div class="ContentForm">
<form action="" method="post" name="FormEntrar">
<div class="input-group input-group-lg">
<span class="input-group-addon" id="sizing-addon1"><i class="glyphicon glyphicon-envelope"></i></span>
<input type="email" class="form-control" name="correo" placeholder="Correo" id="Correo" aria-describedby="sizing-addon1" required>
</div>
<br>
<div class="input-group input-group-lg">
<span class="input-group-addon" id="sizing-addon1"><i class="glyphicon glyphicon-lock"></i></span>
<input type="password" name="contra" class="form-control" placeholder="******" aria-describedby="sizing-addon1" required>
</div>
<br>
<button class="btn btn-lg btn-primary btn-block btn-signin" id="IngresoLog" type="submit">Entrar</button>
<div class="opcioncontra"><a href="">Olvidaste tu contraseña?</a></div>
</form>
</div>
</div>
</body>
<!-- vinculando a libreria Jquery-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!-- Libreria java scritp de bootstrap -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</html>
Descarga el ejemplo completo:
Sistema de logeo en PHP 10KBEspero que le ayude este articulo, si no realizar sugerencias, dudas en el comentario, saludos para todos.
Hola me deja este error
Warning: mysqli::__construct(): (HY000/1049): Unknown database ‘logeo’ in G:\xampp\htdocs\sistema_login\determ.php on line 81
Warning: mysqli::query(): Couldn’t fetch mysqli in G:\xampp\htdocs\sistema_login\determ.php on line 93
Notice: Trying to get property of non-object in G:\xampp\htdocs\sistema_login\determ.php on line 98
como hallaste la solucion¿?
Disculpa ya encontre el error, esta bueno tu ayuda
Donde debo ingresar la direccion para continuar con el proyecto?
me aparece que la contraseña es incorrecta y ya ingrese un usuario nuevo, que podria ser el problema?
Usuario:marcos@gmail.com
Contrseña:test12345
Para agregar nuevos usuarios: la contraseña debe ser incriptada con la clase PHPass, tal como se ve en el siguiente ejemplo.
HashPassword(«micontrasena»);
echo $Clave;
?>
estimado buenas si me ejecuta tu codigo pero cuando hago la prueba me dice contraseña incorrecta, no se mucho en que debo generar el password en md5 o hash1 porfa tu apoyo.
He aquí un ejemplo como generar:
La contraseña generado en el ejemplo se usa la misma clase PasswordHash.Class.php.
hola estimado Rodrigo.
He copiado y pegado tu código php para generar contraseñas y todas son invalidadas por tu sistema.
Me da contraseñas como esta y nada…
$2a$08$ooRXqJ2.JngnzeAEgwFElO6T5lB502c1IhwmFkyHtMFMfzfxpa5g2
hola rodrigo, he generado la clave como tu lo haces en el ejemplo, genere con md5, con hash1 y nada todas son invalidadas, te agradezco su colaboración, gracias
Estimados, espero que no sea tarde…
Para quienes tienen problemas con el PasswordHash y CheckPassword porque siempre sale contraseña incorrecta…
eliminen las comillas «» antes y después de «micontrasena», proque la funcion las toma en cuenta como parte del password.
Saludos
Hola, te comento tengo problemas con el password, es decir dejando todo como esta si funciona el chequeo del correo pero deja pasar cualquier contraseña como correcta. He hecho los cambios que sugieres quitarle las comillas pero si les quito las comillas a la contraseña entonces ninguna contraseña la acepta ni la correcta. Como hicistes para corregir esto please. Gracias.
Para no perder el hilo de mi consulta, ya encontre el error, realmente antes de ejecutar toda la aplicacion, se debe primero crear las contraseñas encryptadas ejecutando en un archivo aparte si es que asi lo desea:
HashPassword(“micontrasena”);
echo $Clave;
?>
donde debe colocar su password en «microntrasena», por ejemplo cuando coloco un numero debo colocar ‘5317708’ y asi si lo genera totalmente, despues si podemos ejecutar sin problema y funciona a la perfeccion, espero sea util mi comentario.
este es el error que tengo con este scrip al insertar los credenciales
The requested URL /admin.php was not found on this server.
gracias me sirvio tu ejemplo sigue adelante con tu curso
Solucion para los que les da error: Agregar un usuario en la tabla de la base de datos, y la clave pasarla a la seguriad hash en: https://phppasswordhash.com/
Estimado: Estoy usando tu código con PHP 8 y marca errores en las líneas 137, 138 y 139 de PasswordHash.Class.php; podrás apoyarnos con la actualización del código?
Hola. como estas Nairda. voy actualizar el código. gracias por tu comentario.