Jump to content

Resource id#51


EmmanuelCorrea

Recommended Posts

Another couple of changes that I recommend you to make.

  1. Do not store passwords in plain text - too insecure. Use password_hash() when storing and password_verify() to check on login.
  2. Store your session variables as $_SESSION['usuario'] and $_SESSION['puesto'] - so you know who is logged in in what they are allowed to do.
Link to comment
Share on other sites

10 hours ago, Barand said:

In my PDO example, "SELECT puesta ..." should be "SELECT puesto ..."

try


    session_start();

    /***********************************************************
    **   PDO CONNECTION
    ************************************************************/
            $host     = 'localhost';
            $username = '?';                                     // provide your credentials
            $password = '?';
            $database = '?';
            
            $dsn = "mysql:dbname=$database; host=$host; charset=utf8";

            $db = new pdo($dsn, $username, $password, 
                [
                    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                    PDO::ATTR_EMULATE_PREPARES => false,
                    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
                ]);
    /***********************************************************/
        
    if ($_SERVER['REQUEST_METHOD'] == 'POST') {      // was data posted to the page?
        $usuario = $_POST['nomUsuario'];
        $contrasena = $_POST['inContra'];
        

        $stmt = $db->prepare("SELECT puesto FROM usuario WHERE usuario = ? AND contrasena = ? ");
        $stmt->execute( [$usuario, $contrasena] );
        $verificar = $stmt->rowCount();
        if($verificar==1){
            //El logueo es exitoso y se crea la sesion
            if($valores = $stmt->fetch()){
                if($valores['puesto'] == 'A'){
                    $_SESSION['usuario'] = $usuario;
                }else if($valores['puesto'] == 'B'){
                    $_SESSION['alumno'] = $usuario;
                    header("HTTP/1.1 302 Moved Temporarily");
                    header("Location: ../../../alumnos/php/indexMenu.php");          
                }
            }           
        } else {
            unset($_SESSION['usuario'], $_SESSION['alumno']);
            echo 'No se ha podido iniciar sesion, por favor vuelva a intentarlo.';
        }
    }

You can use this code to check if the session variables were set correctly


echo '<pre>', print_r($_SESSION, 1), '</pre>';

 

 

I made the change to PDO.

<?php
    session_start ();
            $host = 'localhost';
            $username = '*************'; // proporciona tus credenciales
            $password = '*************';
            $database = 'itzitacu_app';
            
            $dsn="mysql:dbname=$database;host=$host;charset=utf8";

    $db=new pdo($dsn,$username,$password,[PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,PDO::ATTR_EMULATE_PREPARES=>false,
        PDO::ATTR_DEFAULT_FETCH_MODE=>PDO::FETCH_ASSOC]);        
    if ($_SERVER['REQUEST_METHOD']=='POST') {      // was data posted to the page?
        $usuario = $_POST['nomUsuario'];
        $contrasena = $_POST['inContra'];
        
        $stmt=$db->prepare("SELECT * FROM usuario WHERE usuario = '%s' AND contrasena = '%s' ");
        $stmt->execute( [$usuario, $contrasena] );
        $verificar = $stmt->rowCount();
        if($verificar==1){
            //El logueo es exitoso y se crea la sesion
            if($valores = $stmt->fetch()){
                if($valores['puesto'] == 'A'){
                    $_SESSION['usuario'] = $usuario;
                  header("HTTP/1.1 302 Moved Temporarily");
                  header("Location: ../indexMenu.php");
                }else if($valores['puesto'] == 'B'){
                    $_SESSION['alumno'] = $usuario;
                    header("HTTP/1.1 302 Moved Temporarily");
                    header("Location: ../../../alumnos/php/indexMenu.php");          
                }
            }           
        } else {
            unset($_SESSION['usuario'], $_SESSION['alumno']);
            echo 'No se ha podido iniciar sesion, por favor vuelva a intentarlo.';
        }
}echo '<pre>', print_r($_SESSION, 1), '</pre>';

 

 

What happens is that it does not enter to verify if the user exists and to do the login. And the session code sends me:

 

Array

(

)

Link to comment
Share on other sites

2 minutes ago, Barand said:

My query was


$stmt = $db->prepare("SELECT puesto FROM usuario WHERE usuario = ? AND contrasena = ? ");

Yours is


$stmt=$db->prepare("SELECT * FROM usuario WHERE usuario = '%s' AND contrasena = '%s' ");

 

 

Yes, because username and password are taken from the user and password that are entered. Then verify in the database if it exists, if so it gives you access. 

You can see it in the following image.

Sin título.jpg

Link to comment
Share on other sites

When using PDO with a prepared statement, the ?s are placeholders for the parameters (in this case username and password)

The execute statement then passes the parameters to the query. This way the query and paramter values are separate and therefor secure from SQL hacks.

        $stmt = $db->prepare("SELECT puesto FROM usuario WHERE usuario = ? AND contrasena = ? ");    // query with placeholders  
        $stmt->execute( [$usuario, $contrasena] );                                                   // execute passing the values 

Your version of the query will look for a user whose username is "%s" and passwrod is "%s", which is why it fails.

Link to comment
Share on other sites

1 minute ago, Barand said:

Al usar PDO con una declaración preparada, los? S son marcadores de posición para los parámetros (en este caso, nombre de usuario y contraseña)

La instrucción execute luego pasa los parámetros a la consulta. De esta forma, los valores de consulta y paramter son independientes y, por lo tanto, seguros de los hacks de SQL.


Su consulta buscará un usuario cuyo nombre de usuario sea "% s" y passwrod es "% s", por lo que falla.

 

Hell, you're right, I just analyzed the query, where it verifies if the user and password depend on A or B to give access according to the puesto.

 

Now modify that part. And this the result.

Which is correct because it receives that A from the puesto. 

....Now the detail is that I keep sending the blank page.

Sin título1.jpg

Link to comment
Share on other sites

Your code doesn't output anything (except the added check to see the contents of the session). All it does is check the user and password and update session variables. It then shoud transfer to another page.

As it transfers before you do the print_r() you don't see anything.  Comment out those header calls while you are testing.

Link to comment
Share on other sites

If you decide to take my advice in my earlier reply to hash your passwords, this script will update your current contrasena plain-text values to their hashed values

<?php
    /***********************************************************
    **   PDO CONNECTION                                       **
    ************************************************************/
            $host     = 'localhost';
            $username = '?';
            $password = '?';
            $database = '?';
            
            $dsn = "mysql:dbname=$database; host=$host; charset=utf8";

            $db = new pdo($dsn, $username, $password, 
                [
                    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                    PDO::ATTR_EMULATE_PREPARES => false,
                    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
                ]);
    /***********************************************************/
    
    //  Make sure contrasena column big enough for hash value
    $db->exec("ALTER TABLE `usuario` CHANGE COLUMN `contrasena` `contrasena` VARCHAR(100) NULL DEFAULT NULL");
    
    // prepare a statememt to update the usuario records 
    $updt = $db->prepare("UPDATE usuario SET contrasena = ? WHERE id_usu = ? ");

    // get existing usuario records and update contrasena column with hash value
    $res = $db->query("SELECT id_usu, contrasena FROM usuario");
    foreach ($res as $r) {
        $hash = password_hash($r['contrasena'], PASSWORD_DEFAULT);
        $updt->execute( [ $hash, $r['id_usu'] ] );
    }
   
?>

Then your current code might now look like this

    session_start();
    unset($_SESSION['usuario'], $_SESSION['puesto']);
    /***********************************************************
    **   PDO CONNECTION                                       **
    ************************************************************/
            $host     = 'localhost';
            $username = '?';
            $password = '?';
            $database = '?';
            
            $dsn = "mysql:dbname=$database; host=$host; charset=utf8";

            $db = new pdo($dsn, $username, $password, 
                [
                    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                    PDO::ATTR_EMULATE_PREPARES => false,
                    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
                ]);
    /************************************************************/
        
    if ($_SERVER['REQUEST_METHOD'] == 'POST') {
        $usuario = $_POST['nomUsuario'];
        $contrasena = $_POST['inContra'];

        $stmt = $db->prepare("SELECT contrasena, puesto FROM usuario WHERE usuario = ?");
        $stmt->execute( [$usuario] );
        
        if($valores = $stmt->fetch()){
            if (password_verify($contrasena, $valores['contrasena'])) {
                //El logueo es exitoso y se crea la sesion
                $_SESSION['usuario'] = $usuario ;
                $_SESSION['puesto'] = $valores['puesto'];
                echo '<pre>', print_r($_SESSION, 1), '</pre>';                   // !!! DEBUG only -- remove
                switch ($valores['puesto'])  {
                    case 'A':
                        header("Location: ../indexMenu.php");
                        exit;
                    case 'B':
                        header("Location: ../../../alumnos/php/indexMenu.php"); 
                        exit;   
                }
            }
        }
        echo 'No se ha podido iniciar sesion, por favor vuelva a intentarlo.';
    }

Note the "exit;" statements after the redirect calls. This prevents the script from continuing execution (even though you won't see it) and creating unwanted side effects (such as db updates etc.)

Link to comment
Share on other sites

EmmanuelCorrea, It seems like you solved your original goal, but I thought I would share the following function.  It mimics PDO so you can see the actual query, and I find very helpful for troubleshooting.

 

<?php

function showQuery($sql, $data) {
    $keys = [];
    $values = [];
    foreach ($data as $key=>$value) {
        $keys[] = is_string($key)?'/:'.$key.'/':'/[?]/';
        $values[] = is_numeric($value)?$value:"'$value'";
    }
    return preg_replace($keys, $values, $sql, 1, $count);
}

$sql="SELECT puesto FROM usuario WHERE usuario = :usuario AND contrasena = :contrasena";
$data=['usuario'=>'NotionCommotion', 'contrasena'=>'notTelling'];
echo(showQuery($sql, $data)."\n\n");    //Either echo or log the results
syslog(LOG_INFO, showQuery($sql, $data));

$sql="SELECT puesto FROM usuario WHERE usuario = ? AND contrasena = ?";
$data=['NotionCommotion', 'notTelling'];
echo(showQuery($sql, $data)."\n\n");    //Either echo or log the results
syslog(LOG_INFO, showQuery($sql, $data));
//... $stmt = $db->prepare($sql);

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.