0

When a user accesses the website through the login, a page profile.php is displayed which shows the user's data (the password is not shown) in a table and displays a form to modify this data. The problem is that all the data is modified correctly except the password, which is modified but it is not the one sent by the form.

Connection to the database:

<?php

include('../php/.env.php');

class DB {

    public function __construct()
    {
        if ($_SESSION['usuario'][2] != 'admin' || $_SESSION['usuario'][2] != 'user') {
            header('location:../php/login.php');
            exit();
        }
    }

    public static function conn()
    {
        // conexión a la base de datos
        try {
            $conn = new PDO("mysql:host=" . SERVIDOR . ";dbname=" . BD, USUARIO, PASSWORD);
            $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            return $conn;
        } catch (PDOException $e) {
            echo 'HA FALLADO LA CONEXIÓN: ' . $e->getMessage();
        }
    }
}

perfi.php (form)

<?php
            <div class="container p-4">
                <div class="row">
                    <div class="col-md-5 mt-4">
                        <div class="border">
                            <div class="card-body">
                                <!-- form no tiene el atributo action porque lo vamos a procesar por JS -->
                                <form class="form" id="form-editar">
                                    <input type="hidden" id="idUser"/>
                                    <div class="form-label">
                                        <input type="text" id="nombre" placeholder="Nombre" class="form-control mb-3" />
                                        <input type="text" id="apellidos" class="form-control mb-3" placeholder="Apellidos">
                                        <input type="tel" id="telefono" class="form-control mb-3" placeholder="Teléfono">
                                        <input type="text" id="direccion" class="form-control mb-3" placeholder="Dirección">
                                        <input type="password" id="contrasena" class="form-control mb-3" autocomplete="off" placeholder="Contraseña">
                                    </div>
                                    <button type="submit" class="btn btn-primary col-12 text-center">
                                        Actualizar perfil
                                    </button>
                                </form>
                            </div>
                        </div>
                    </div>
                    <div class="col-md-7 text-center mt-4">
                        <table class="table table-bordered table-sm">
                            <thead>
                                <tr>
                                    <td>Id</td>
                                    <td>Nombre</td>
                                    <td>Apellidos</td>
                                    <td>Teléfono</td>
                                    <td>Dirección</td>
                                    <td>Modificar perfil</td>
                                </tr>
                            </thead>
                            <tbody id="datos"></tbody>
                        </table>
                    </div>
                </div>
            </div>

MYSQL

users_data contains: idUser(PK), first name, last name, phone number, address

users_login contains: idLogin, idUser(FK), usuario, contrasena, rol

datos.php (shows the user's data )

<?php
// realiza una consulta a la bbdd de los datos del usuario y las envía al navegador

include('./DB.php');

session_start();

if ($_SESSION['usuario'][2] == 'user' || $_SESSION['usuario'][2] == 'admin') {


    $conexion = DB::conn();
    $sentencia = "SELECT * FROM users_data WHERE idUser = :idUser";
    $consulta = $conexion->prepare($sentencia);
    $consulta->execute(array(':idUser' => $_SESSION['usuario'][0]));

    $json = [];
    while ($row = $consulta->fetch(PDO::FETCH_ASSOC)) {
        $json[] = [
            'idUser' => $row['idUser'],
            'nombre' => $row['nombre'],
            'apellidos' => $row['apellidos'],
            'telefono' => $row['telefono'],
            'direccion' => $row['direccion']
        ];
    }
    $consulta->closeCursor();
    $conexion = null;
    $jsonstring = json_encode($json);
    echo $jsonstring;
} else {
    header('location:../php/login.php');
}

prueba.php (it shows the user's data in the form for its later modification)

<?php

include('./DB.php');

session_start();

    $conexion = DB::conn();
    $sentencia = "SELECT * FROM users_data WHERE idUser = :idUser";
    $consulta = $conexion->prepare($sentencia);
    $consulta->execute(array(':idUser' => $_POST['idUser']));

    $json = [];
    while ($row = $consulta->fetch(PDO::FETCH_ASSOC)) {
        $json[] = [
            'idUser' => $row['idUser'],
            'nombre' => $row['nombre'],
            'apellidos' => $row['apellidos'],
            'telefono' => $row['telefono'],
            'direccion' => $row['direccion']
        ];
    }

    $consulta->closeCursor();
    $conexion = null;
    $jsonstring = json_encode($json[0]);
    echo $jsonstring;

modificarDatos.php (modifies the user data in the table users_data and users_login.)

include('./DB.php');

session_start();

if (isset($_POST['idUser'])) {
    $idUser = filter_input(INPUT_POST, 'idUser', FILTER_SANITIZE_NUMBER_INT, FILTER_VALIDATE_INT);
    $nombre = htmlentities($_POST['nombre']);
    $apellidos = htmlentities($_POST['apellidos']);
    $telefono = filter_input(INPUT_POST, 'telefono', FILTER_SANITIZE_NUMBER_INT, FILTER_VALIDATE_INT);
    $direccion = htmlentities($_POST['direccion']);
    $pass = htmlentities($_POST['contrasena']);
    $contrasena = password_hash($pass, PASSWORD_BCRYPT);


    $conexion = DB::conn();
    $sentencia = "UPDATE users_data SET nombre = :nuevoNombre, apellidos = :nuevoApellido, telefono = :nuevoTelefono, direccion = :nuevaDireccion  WHERE idUser = $idUser";
    $consulta = $conexion->prepare($sentencia);
    $consulta->bindParam(":nuevoNombre", $nombre);
    $consulta->bindParam("nuevoApellido", $apellidos);
    $consulta->bindParam(":nuevoTelefono", $telefono);
    $consulta->bindParam(":nuevaDireccion", $direccion);
    $consulta->execute();
    $sentencia2 = "UPDATE users_login SET contrasena = :nuevaContrasena WHERE idLogin = $idUser";
    $consulta = $conexion->prepare($sentencia2);
    $consulta->bindParam(":nuevaContrasena", $contrasena);
    $consulta->execute();

}

JS - AJAX

$(document).ready(function () {
  console.log("jQuery esta funcionando");

  // obtains user data
  function mostrarDatos() {
    $.ajax({
      type: "GET",
      url: "datos.php", 
      success: (response) => {
        let datos = JSON.parse(response);
        let template = "";

        datos.forEach((dato) => {
          // scrolls through and displays user data
          template += `
            <tr idUser="${dato.idUser}"class="align-middle">
              <td>${dato.idUser}</td>
              <td>${dato.nombre}</td>
              <td>${dato.apellidos}</td>
              <td>${dato.telefono}</td>
              <td>${dato.direccion}</td>
              <td>
                <button class="edit-datos btn btn-danger">
                  Modificar datos
                </button>
              </td>
            </tr>
          `;
        });
        $("#datos").html(template);
      },
    });
  }
  mostrarDatos();

  // displays the user data in the form so that they can be modified
  $(document).on("click", ".edit-datos", () => {
    let element = $(this)[0].activeElement.parentElement.parentElement;
    let idUser = $(element).attr("idUser");
    $.post("prueba.php", { idUser }, (response) => {
      let datos = JSON.parse(response);
      $("#idUser").val(datos.idUser);
      $("#nombre").val(datos.nombre);
      $("#apellidos").val(datos.apellidos);
      $("#telefono").val(datos.telefono);
      $("#direccion").val(datos.direccion);
      $("#contrasena").val(datos.contrasena);
    });
  });

  $("#form-editar").submit((e) => {
    e.preventDefault();
    const postData = {
      idUser: $("#idUser").val(),
      nombre: $("#nombre").val(),
      apellidos: $("#apellidos").val(),
      telefono: $("#telefono").val(),
      direccion: $("#direccion").val(),
      contrasena: $("#contrasena").val()
    };
    $.post("modificarDatos.php", postData, (response) => {
      mostrarDatos(response);
      $("#form-editar").trigger("reset"); // resetea el formulario
    });
  });
});
15
  • 2
    "UPDATE users_login SET contrasena = :nuevaContrasena WHERE idLogin = $idUser"; You are vulnerable to SQL injection, use parameter binding all all the parameters here. Commented Dec 21, 2022 at 16:04
  • 1
    "which is modified but it is not the one sent by the form" What does this mean? You're hashing the provided password with password_hash() (as you should), so the value that gets stored in the database isn't going to be the plain text password that the user types. Commented Dec 21, 2022 at 16:07
  • @AlexHowansky I don't understand what you mean by 'use parameter binding all all the parameters here' Commented Dec 21, 2022 at 16:08
  • 1
    Also note, you are not checking that the user is logged in before allowing them to change a password. So, any user can change any other user's password by hitting that endpoint directly. You need to prompt for the current password, and check that it's correct, before making the changes. Commented Dec 21, 2022 at 16:08
  • 1
    You should be binding a value for idUser: "UPDATE users_login SET contrasena = :nuevaContrasena WHERE idLogin = :idUser"; like you do in prueba.php. Commented Dec 21, 2022 at 16:09

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.