Aprende a implementar fácilmente un sistema de usuario con FOSUserBundle (Doctrine y MySql) en Symfony 2.


Crear un sistema de usuario con Symfony 2 o 3 "no" es una tarea difícil. La página de inicio le ofrece una introducción rápida de cómo crear un proveedor de usuario personalizado para su aplicación aquí .

Pero, ¿qué podría ser mejor que algo que ya está implementado y se usa para muchos desarrolladores de Symfony y se mantiene actualmente en Github? tal vez cree su propio proveedor de usuarios , porque eso sería auto satisfactorio, para su conocimiento y su dev-ego. pero perderá un tiempo de desarrollo precioso en algo que podría instalar en menos de 30 minutos y proporcionaría las mismas funciones que necesita para crear desde el principio.

¿Por qué FOSUserBundle?

El FOSUserBundle agrega soporte para un sistema de usuario respaldado por una base de datos en Symfony2. Proporciona un marco flexible para la gestión de usuarios que tiene como objetivo manejar tareas comunes como el registro de usuarios y la recuperación de contraseñas.

Las características incluyen:

  • Los usuarios se pueden almacenar a través de Doctrine ORM, MongoDB / CouchDB ODM o Propel (usaremos Doctrine en este caso)
  • Soporte de registro, con una confirmación opcional por correo electrónico
  • Soporte para restablecimiento de contraseña

Este artículo te enseñare cómo configurar fácilmente FOSUserBundle en tu proyecto (con clases de usuarios y grupos ), y no fallarás en esta tarea, eso es una promesa.

1. Cree un paquete de usuario (opcional)

Crea un nuevo paquete en la carpeta /src de tu proyecto Symfony usando el comando php bin/console generate:bundle en Symfony. El punto principal de esto es aislar la administración de usuarios en un solo paquete. La estructura de un paquete no necesita ser especial, solo necesita estar registrado en el Kernel y todo funcionará correctamente .

Nota

En caso de que no desee crear un paquete adicional para el sistema del usuario, simplemente siga los siguientes pasos en un paquete existente .

2. Cree User.php y Group.php

El objetivo de este paquete es conservar alguna clase de usuario en una base de datos. Su primer trabajo, entonces, es crear la clase de Usuario para su aplicación . Esta clase puede verse y actuar como desee: agregue propiedades adicionales (campos para la tabla de usuario) o métodos que pueda encontrar útiles.

Si decidió crear un paquete adicional, probablemente no tendrá la Entitycarpeta dentro, por lo tanto, debe crear una nueva carpeta con el nombre Entity. Dentro de la carpeta Entity del paquete, cree 2 archivos User.php y Group.php.

User.php

La clase de usuario debe tener el siguiente código dentro:

<?php
// src/Acme/UserBundle/Entity/User.php
// Cambie el espacio de nombres de acuerdo con la ruta en su proyecto
namespace userBundle\Entity;

// Usando FOSUserBundle 1.3x, la clase de usuario se ubicará en su lugar en:
// use FOS\UserBundle\Entity\User as BaseUser;

use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="fos_user")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    
    // Cambie la ruta targetEntity si desea crear el grupo
    
    /**
     * @ORM\ManyToMany(targetEntity="userBundle\Entity\Group")
     * @ORM\JoinTable(name="fos_user_user_group",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")}
     * )
     */
    protected $groups;

    public function __construct()
    {
        parent::__construct();
        // tu propia lógica
    }
}

Group.php

La clase de grupo debe tener el siguiente código dentro:

<?php

// Cambie el espacio de nombres de acuerdo con la ruta en su proyecto
namespace userBundle\Entity;

use FOS\UserBundle\Model\Group as BaseGroup;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="fos_group")
 */
class Group extends BaseGroup
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
     protected $id;
}

Finalmente, su paquete debería verse así:

FosUserBundle implementation example

El userBundle se ha creado directamente en la carpeta /src del proyecto Symfony, por lo que el espacio de nombres de las clases es namespace userBundle\Entity;

3. Cambiar el proveedor de usuarios predeterminado

Ahora que existe su clase de usuario, debe habilitar la clase FOSUserBundle como su proveedor de usuario predeterminado en su proyecto. Debe agregar la configuración en el archivo config.yml de su proyecto, especifica el controlador de su base de datos, la ruta del usuario y la clase de grupo como se muestra en el siguiente ejemplo, agregue el fragmento en su archivo config.yml y cambie la ruta a las clases si necesita:

# /app/config.yml
fos_user:
    db_driver: orm
    firewall_name: main
    user_class: userBundle\Entity\User
    group:
        group_class: userBundle\Entity\Group

Ahora su clase se utilizará como proveedor de usuarios predeterminado.

4. Actualice la configuración de seguridad

Necesita modificar el archivo security.yml de su proyecto y agregar la siguiente configuración. Comente todo el contenido existente en este archivo o elimínelo y reemplácelo con:

# app/config/security.yml
security:
    encoders:
        FOS\UserBundle\Model\UserInterface: bcrypt

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username

    firewalls:
        main:
            pattern: ^/
            form_login:
                provider: fos_userbundle
                csrf_token_generator: security.csrf.token_manager
                # Si está usando Symfony <2.8, use la siguiente configuración en su lugar:
                # csrf_provider: form.csrf_provider

            logout:       true
            anonymous:    true

    access_control:
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/, role: ROLE_ADMIN }

Recuerda (según la versión de tu proyecto Symfony) cambiar la  csrf_token_generatorpropiedad en los firewalls si no funciona la primera vez.

5. Instale FOSUserBundle con composer

Es posible que se esté preguntando por qué este paso no es el primer paso, ya que es el punto principal de este artículo. Bueno, la respuesta es bastante simple. En casi todos los tutoriales, el primer paso es instalar el FOSUserBundle usando Composer, sin embargo, en las últimas versiones de Symfony, esto dará lugar al error conocido:

El nodo hijo "db_driver" en la ruta "fos_user" debe estar configurado.

El problema solo se debe al orden en el que ejecuta los pasos de instalación. Para continuar, incluye el paquete con Composer:

composer require friendsofsymfony/user-bundle "[email protected]"

O agregue la línea a su línea composer.json y luego ejecute composer install:

"require":{
  "friendsofsymfony/user-bundle": "~2.0[email protected]"
}

Sin embargo, después de que se complete la instalación de FOSUserBundle, probablemente enfrentará una última excepción :

[Symfony \ Component \ Config \ Exception \ FileLoaderLoadException] No hay una extensión que pueda cargar la configuración para fos_user

Verá este error simplemente porque no hemos habilitado el paquete en el AppKernel.phparchivo, por lo tanto, debe ubicar el archivo app/AppKernel.php y registrar el paquete:

<?php
// app/AppKernel.php

public function registerBundles()
{
    $bundles = array(
        new FOS\UserBundle\FOSUserBundle(),
    );
}

6. Habilite las rutas predeterminadas

La estructura de FOSUserBundle está lista; sin embargo, sin rutas en su aplicación, no podría usar el paquete, por lo tanto, necesitamos importar el enrutamiento desde FOSUserBundle a las rutas de su aplicación. Para habilitar las rutas predeterminadas (inicio de sesión, registro, cierre de sesión, etc.) agregando las siguientes líneas en su archivo app/routing.yml:

# app/config/routing.yml
fos_user:
    resource: "@FOSUserBundle/Resources/config/routing/all.xml"

# IMPORTANT
# Import the following routes only if when you start the project
# those routes are not available :

fos_user_profile:
    resource: "@FOSUserBundle/Resources/config/routing/profile.xml"
    prefix: /profile

fos_user_register:
    resource: "@FOSUserBundle/Resources/config/routing/registration.xml"
    prefix: /register

fos_user_resetting:
    resource: "@FOSUserBundle/Resources/config/routing/resetting.xml"
    prefix: /resetting

fos_user_change_password:
    resource: "@FOSUserBundle/Resources/config/routing/change_password.xml"
    prefix: /profile

7. Actualice el esquema de la base de datos.

Después de toda la configuración básica requerida, solo necesita actualizar la base de datos para crear las tablas donde se insertarán sus usuarios usando el comando Symfony:

Para Symfony 2.x, la consola está en el directorio de la aplicación:

php app/console doctrine:schema:update --force

Y para Symfony 3.x, la consola está en el directorio bin:

php bin/console doctrine:schema:update --force

Nota

En caso de que obtenga la excepción The child node "from_email" at path "fos_user" must be configuredlea este artículo para saber cómo resolverla .

8.Pruebe su sistema de usuario

Ahora necesita probar si todo funciona, recuerde borrar el caché primero. Registre el primer usuario en la siguiente URL: 

http://yourapp/app_dev.php/register

E inicie sesión en:

http://yourapp/app_dev.php/login

Que te diviertas ❤️!


Ingeniero de Software Senior en EPAM Anywhere. Interesado en la programación desde los 14 años, Carlos es un programador autodidacta, fundador y autor de la mayoría de los artículos de Our Code World.

Conviertete en un programador más sociable

Patrocinadores