En este artículo, aprenderás cómo configurar la autenticación de usuario en PHP usando el componente de seguridad de Symfony. Además de la autenticación, le mostraré cómo utilizar su autorización basada en roles, que puede ampliar según sus necesidades..
El componente de seguridad de Symfony te permite configurar funciones de seguridad como autenticación, autorización basada en roles, tokens CSRF y mucho más fácilmente. De hecho, se divide en cuatro subcomponentes que puede elegir de acuerdo con sus necesidades.
El componente de seguridad tiene los siguientes subcomponentes:
En este artículo, vamos a explorar la función de autenticación proporcionada por el Symfony / Security-Core componente.
Como de costumbre, comenzaremos con las instrucciones de instalación y configuración, y luego exploraremos algunos ejemplos reales para demostrar los conceptos clave.
En esta sección, vamos a instalar el componente de seguridad de Symfony. Supongo que ya ha instalado Composer en su sistema; lo necesitaremos para instalar el componente de seguridad disponible en Packagist.
Así que adelante, instale el componente de seguridad con el siguiente comando.
$ compositor requiere symfony / seguridad
En nuestro ejemplo, vamos a cargar usuarios desde la base de datos MySQL, por lo que también necesitaremos una capa de abstracción de la base de datos. Instalemos una de las capas de abstracción de bases de datos más populares: Doctrine DBAL.
$ compositor requiere doctrina / dbal
Eso debería haber creado el compositor.json archivo, que debería verse así:
"require": "symfony / security": "^ 4.1", "doctrine / dbal": "^ 2.7"
Vamos a modificar el compositor.json archivo para parecerse a la siguiente.
"require": "symfony / security": "^ 4.1", "doctrine / dbal": "^ 2.7", "autoload": "psr-4": "Sfauth \\": "src" , "mapa de clase": ["src"]
Como hemos añadido un nuevo mapa de clase
entrada, avancemos y actualicemos el cargador automático del compositor ejecutando el siguiente comando.
$ compositor dump -o
Ahora, puedes usar el Sfauth
espacio de nombres para autocargar clases bajo la src directorio.
Así que esa es la parte de la instalación, pero ¿cómo se supone que la uses? De hecho, solo es cuestión de incluir el autoload.php archivo creado por Composer en su aplicación, como se muestra en el siguiente fragmento de código.
En primer lugar, analicemos el flujo de autenticación habitual proporcionado por el componente de seguridad de Symfony.
Interfaz de usuario
interfaz.En nuestro ejemplo, vamos a hacer coincidir las credenciales del usuario con la base de datos MySQL, por lo que tendremos que crear el proveedor del usuario de la base de datos. También crearemos el proveedor de autenticación de base de datos que maneja la lógica de autenticación. Y finalmente, crearemos la clase Usuario, que implementa la Interfaz de usuario
interfaz.
En esta sección, crearemos la clase de usuario que representa la entidad del usuario en el proceso de autenticación..
Sigue adelante y crea el src / User / User.php archivo con los siguientes contenidos.
username = $ username; $ this-> password = $ password; $ this-> roles = $ roles; función pública getUsername () return $ this-> username; función pública getPassword () return $ this-> password; función pública getRoles () return explode (",", $ this-> roles); public function getSalt () return "; public function eraseCredentials ()
Lo importante es que la clase Usuario debe implementar Symfony Security. Interfaz de usuario
interfaz. Aparte de eso, no hay nada fuera de lo común aquí..
Es responsabilidad del proveedor del usuario cargar usuarios desde el back-end. En esta sección, crearemos el proveedor de usuarios de la base de datos, que carga al usuario desde la base de datos MySQL..
Vamos a crear el src / User / DatabaseUserProvider.php archivo con los siguientes contenidos.
conexión = $ conexión; public function loadUserByUsername ($ username) return $ this-> getUser ($ username); función privada getUser ($ username) $ sql = "SELECT * FROM sf_users WHERE username =: name"; $ stmt = $ this-> connection-> prepare ($ sql); $ stmt-> bindValue ("nombre", $ nombre de usuario); $ stmt-> execute (); $ row = $ stmt-> fetch (); if (! $ row ['username']) $ exception = new UsernameNotFoundException (sprintf ('Nombre de usuario "% s" no encontrado en la base de datos.', $ row ['username'))); $ exception-> setUsername ($ username); lanzar $ excepción; else devolver usuario nuevo ($ fila ['nombre de usuario'], $ fila ['contraseña'], $ fila ['roles']); función pública refreshUser (UserInterface $ user) if (! $ user instanceof User) lanzar una nueva excepción UnsupportedUserException (sprintf ('No se admiten las instancias de "% s"., get_class ($ user))); devolver $ this-> getUser ($ user-> getUsername ()); la función pública admite Clase ($ clase) return 'Sfauth \ Usuario \ Usuario' === $ clase;
El proveedor usuario debe implementar el UserProviderInterface
interfaz. Estamos utilizando la doctrina DBAL para realizar las operaciones relacionadas con la base de datos. Como hemos implementado el UserProviderInterface
interfaz, debemos implementar el loadUserByUsername
, refreshUser
, y apoya clase
metodos.
los loadUserByUsername
El método debe cargar al usuario por el nombre de usuario, y eso se hace en el getUser
método. Si se encuentra el usuario, devolvemos el correspondiente Sfauth \ Usuario \ Usuario
objeto, que implementa el Interfaz de usuario
interfaz.
Por otro lado, la refreshUser
método refresca el suministrado Usuario
objeto mediante la obtención de la información más reciente de la base de datos.
Y finalmente, el apoya clase
método comprueba si el DatabaseUserProvider
proveedor es compatible con la clase de usuario suministrada.
Finalmente, necesitamos implementar el proveedor de autenticación de usuario, que define la lógica de autenticación: cómo se autentica a un usuario. En nuestro caso, debemos hacer coincidir las credenciales del usuario con la base de datos MySQL, y por lo tanto debemos definir la lógica de autenticación en consecuencia.
Sigue adelante y crea el src / User / DatabaseAuthenticationProvider.php archivo con los siguientes contenidos.
userProvider = $ userProvider; función protegida retrieveUser ($ username, UsernamePasswordToken $ token) $ usuario = $ token-> getUser (); if ($ user instanceof UserInterface) return $ user; prueba $ user = $ this-> userProvider-> loadUserByUsername ($ username); if (! $ user instanceof UserInterface) arroja una nueva AuthenticationServiceException ('El proveedor del usuario debe devolver un objeto UserInterface.'); devolver $ usuario; catch (UsernameNotFoundException $ e) $ e-> setUsername ($ username); lanzar $ e; catch (\ Exception $ e) $ e = new AuthenticationServiceException ($ e-> getMessage (), 0, $ e); $ e-> setToken ($ token); lanzar $ e; función protegida checkAuthentication (UserInterface $ user, UsernamePasswordToken $ token) $ currentUser = $ token-> getUser (); if ($ currentUser instanceof UserInterface) if ($ currentUser-> getPassword ()! == $ user-> getPassword ()) lanza una nueva AuthenticationException ('Las credenciales se cambiaron de otra sesión.'); else else $ password = $ token-> getCredentials (); if (vacío ($ contraseña)) arroja una nueva excepción de autenticación ('La contraseña no puede estar vacía.'); if ($ user-> getPassword ()! = md5 ($ password)) arroja una nueva AuthenticationException ('La contraseña no es válida.');
los DatabaseAuthenticationProvider
proveedor de autenticación extiende el UserAuthenticationProvider
clase abstracta. Por lo tanto, necesitamos implementar el recuperar usuario
y checkAuthentication
métodos abstractos.
El trabajo de la recuperar usuario
El método es cargar al usuario desde el proveedor del usuario correspondiente. En nuestro caso, utilizará el DatabaseUserProvider
Proveedor de usuario para cargar el usuario desde la base de datos MySQL..
Por otro lado, la checkAuthentication
El método realiza las comprobaciones necesarias para autenticar al usuario actual. Tenga en cuenta que he utilizado el método MD5 para el cifrado de contraseñas. Por supuesto, debe utilizar métodos de cifrado más seguros para almacenar las contraseñas de los usuarios..
Hasta ahora, hemos creado todos los elementos necesarios para la autenticación. En esta sección, veremos cómo ponerlo todo junto para configurar la funcionalidad de autenticación.
Sigue adelante y crea el db_auth.php Archivar y rellenar con los siguientes contenidos..
'mysql: // USERNAME: PASSWORD @ HOSTNAME / DATABASE_NAME'), new \ Doctrine \ DBAL \ Configuration ()); // inicie nuestro proveedor de usuario de db personalizado $ userProvider = new DatabaseUserProvider ($ doctrineConnection); // usaremos UserChecker predeterminado, se usa para verificar cheques adicionales como el bloqueo / caducado de la cuenta, etc. // puede implementar su propio implementando la interfaz UserCheckerInterface $ userChecker = new UserChecker (); // inicie nuestro proveedor de autenticación de db personalizado $ dbProvider = new DatabaseAuthenticationProvider ($ userProvider, $ userChecker, 'frontend'); // administrador del proveedor de autenticación de init $ authenticationManager = new AuthenticationProviderManager (array ($ dbProvider)); intente // init un / pw, normalmente obtendrá estos de la variable $ _POST, enviados por el usuario final $ username = 'admin'; $ contraseña = 'admin'; // obtener el token no autenticado $ unauthenticatedToken = new UsernamePasswordToken ($ username, $ password, 'frontend'); // autenticar usuario y obtener el token autenticado $ authenticatedToken = $ authenticationManager-> authenticate ($ unauthenticatedToken); // tenemos el token autenticado (el usuario está conectado ahora), se puede almacenar en una sesión para usar más tarde echo $ authenticatedToken; echo "\ n"; catch (AuthenticationException $ e) echo $ e-> getMessage (); echo "\ n";
Recuerde el flujo de autenticación que se discutió al principio de este artículo: el código anterior refleja esa secuencia.
Lo primero fue recuperar las credenciales del usuario y crear un token no autenticado..
$ unauthenticatedToken = new UsernamePasswordToken ($ username, $ password, 'frontend');
A continuación, hemos pasado ese token al administrador de autenticación para su validación.
// autenticar usuario y obtener el token autenticado $ authenticatedToken = $ authenticationManager-> authenticate ($ unauthenticatedToken);
Cuando se llama al método de autenticación, muchas cosas están sucediendo detrás de escena.
En primer lugar, el administrador de autenticación selecciona un proveedor de autenticación adecuado. En nuestro caso, es el DatabaseAuthenticationProvider
proveedor de autenticación, que será seleccionado para la autenticación.
A continuación, recupera al usuario por el nombre de usuario de DatabaseUserProvider
Proveedor de usuarios. Finalmente, el checkAuthentication
El método realiza las comprobaciones necesarias para autenticar la solicitud del usuario actual..
Si desea probar el db_auth.php guión, tendrás que crear el usuarios_f
tabla en su base de datos MySQL.
CREAR TABLA 'sf_users' ('id' int (11) NOT NULL AUTO_INCREMENT, 'username' varchar (255) NOT NULL, 'password' varchar (255) NOT NULL, 'roles' enum ('registered', 'moderator', 'admin') DEFAULT NULL, PRIMARY KEY ('id')) ENGINE = InnoDB; INSERTE EN LOS VALORES 'sf_users' (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', 'admin');
Sigue adelante y ejecuta el db_auth.php Guión para ver cómo va. Al finalizar con éxito, debe recibir un token autenticado, como se muestra en el siguiente fragmento de código.
$ php db_auth.php UsernamePasswordToken (usuario = "admin", authenticated = true, roles = "admin")
Una vez que el usuario se autentica, puede almacenar el token autenticado en la sesión para las solicitudes posteriores.
Y con eso, hemos completado nuestra demostración de autenticación simple!
Hoy, analizamos el componente de seguridad de Symfony, que te permite integrar funciones de seguridad en tus aplicaciones PHP. Específicamente, discutimos la función de autenticación provista por el subcomponente symfony / security-core, y te mostré un ejemplo de cómo esta funcionalidad se puede implementar en tu propia aplicación..
Siéntase libre de publicar sus pensamientos utilizando la siguiente alimentación!