Encriptación de contraseñas con Symfony
Introducción
Hoy quiero compartir con la comunidad cómo desarrollar un login para empleados en el backoffice y cómo realizar la encriptación de contraseñas con Symfony.
Esta solución ha sido aportada PrestaDevs, una empresa de desarrollo de Prestashop.
Hacer un login para empleados en el backoffice en Prestashop 1.7
Uno de los principales problemas que te vas a encontrar y que trataré de resolver en este post, es realizar la encriptación de contraseña de empleados en Prestashop 1.7 con Symfony.
De lo que trata en este proceso de login, es que el empleado seleccione desde un menú desplegable su nombre de usuario o email, y la contraseña que introduzca sea la misma que tengas ya almacenada al dar de alta a un empleado en tu Prestashop.
Una vez elegido su email e introducido su contraseña, hay que obtener de la base de datos su contraseña encriptada (hay que filtrar por id la tabla ps_employee), y tratar de encriptar la contraseña (en texto plano) que ha introducido el empleado en el campo contraseña.
Aquí está el problema
AQUÍ ESTÁ EL PROBLEMA: hay que encriptar la contraseña igual que lo hace Prestashop 1.7 para luego compararla con la almacenada en la base de datos a ver si son iguales.
En Prestashop 1.6 se podía encriptar con Tools::encrypt($la_contraseña_en_texto_plano), pero en Prestashop 1.7 parece que no es tan sencillo.
La contraseña almacenada en la base de datos es del tipo:
$2y$10$cu17NZHEaIy0qNGYt189Ou1hQjDa7p6UoTCsnPNtwgGWuhvUYT2LG
Si has probado la nueva función que trae Prestashop 1.7 Tools:hash($la_contraseña_en_texto_plano), seguramente lo que te devuelva sea algo así:
8fdf18d292d6922c041713356061e06b
Y lo mismo con hashIV(), etc.. de la clase Tools.
La cuestión es que ahora la encriptación está basada en Symfony.
He desarrollado esta función en PHP para realizar la encriptación de contraseñas con Symfony que compara la contraseña introducida en texto plano por el empleado con la contraseña almacenada en la base de datos y devuelve true si coinciden y false si no:
public static function crypto($plaintextPassword, $passwordHash) { /** @var \PrestaShop\PrestaShop\Core\Crypto\Hashing $crypto */ $crypto = PrestaShop\PrestaShop\Adapter\ServiceLocator::get('\\PrestaShop\\PrestaShop\\Core\\Crypto\\Hashing'); return $crypto->checkHash($plaintextPassword, $passwordHash); }
Y para llamar a esta función hago:
/* Inserted form password */ $plaintextPassword = Tools::getValue('input_password'); /* Selected employee stored password */ $passwordHash = $this->db->getEmployeePassword($id_employee)[0]['passwd']; dump($this->crypto($plaintextPassword, $passwordHash)); if ($this->crypto($plaintextPassword, $passwordHash)) { $output .= $this->displayConfirmation($this->l('Login successful')); } else { $output .= $this->displayError($this->l('ERROR').': '.$this->l('Password incorrect')); }
Y la función que hice para obtener la contraseña del empleado de la base de datos de Prestashop es:
public function getEmployeePassword($id_employee) { return( Db::getInstance()->executeS(' SELECT `passwd` FROM '._DB_PREFIX_.'employee WHERE `id_employee`='.(int)$id_employee.' LIMIT 1 ') ); }
NOTA: me he inspirado en el código que hay en el fichero /classes/Customer.php, en la función getByEmail().
En resumen …
En resumen, puedes utilizar la función $crypto->checkHash($plaintextPassword, $passwordHash), para comparar ambas contraseñas, la cifrada del empleado con la pasada en texto plano desde el formulario.
¡Sígueme en mis redes sociales o en mi página web personal!
Claudio
Hola, si quisiera hacer el login pero fuera de Prestashop en un programa PHP que haga login con los mismos usuarios de la BD de prestashop? Todo dentro del mismo server y accediendo a la misma BD
Andrés Nacimiento García
Hola, si está en el mismo servidor puedes acceder directamente a la base de datos de Prestashop (al fin y al cabo es una base de datos SQL normal y cualquiera) o si no creo que puedes utilizar la API de Prestashop (mira este post a ver si te sirve: https://www.prestashop.com/forums/topic/691747-login-customer-via-webservice/)