Tutorial para instalar FOSUserBundle en Symfony4

Introducción

En este artículo describiré mi experiencia personal instalando FOSUserBundle en Symfony4 para realizar el control de usuarios de una forma sencilla.

Intentaré describir los principales problemas que he encontrado en la instalacion y describiré la forma de solucionarlos.

Advertencia: Los cambios y modificaciones de los archivos de configuración de Symfony son propuestos por mi en base a mi propia experiencia personal, son dados a modo de recomendación, pero queda en responsabilidad de cada uno aplicarlos a su propio criterio y bajo su responsabilidad en los sitios que ustedes administren, en especial aquellos sitios que se encuentren en un servidor de producción.

Requisitos

Lo primero es instalar las dependencias:

Twig

$ composer require twig

Doctrine

Los usuarios de nuestro sitio se encontrarán en una base de datos (mysql), por tanto hay que crear la base de datos primero.

Este paso es opcional, si ya tienes correctamente configurado Doctrine para comunicarse con tu base de datos puedes pasar al siguiente paso.

Creación de la base de datos

Para crear la base de datos, tenemos que indicar donde estará ubicada, para ello modificamos el archivo /App/.env y configuramos lo siguiente

###> doctrine/doctrine-bundle ###
...
DATABASE_URL=mysql://usuariodb:clave@127.0.0.1:3306/dbname
...

donde debemos reemplazar los siguientes valores por los nuestros propios:

  • usuariodb: Usuario de la base de datos
  • clave: Contraseña del usuario de base de datos
  • dbname: Nombre de la base de datos

Luego de eso, procedemos a la creacion de la base de datos con el siguiente comando:

$ php bin/console doctrine:database:create
Created database `dbname` for connection named default

Instalar FOSUserBundle

La instalación de FOSUserBundle se hace mediante composer:

$ composer require friendsofsymfony/user-bundle "~2.0"

Sin embargo al tratar de instalar nos encontraremos con el siguiente error:

The child node "db_driver" at path "fos_user" must be configured.

El mensaje nos indica que debemos configurar la sección “fos_user” de los archivos de configuración de Symfony4.

Lo que haremos será crear un archivo de configuración en la ruta App/config/packages/fos.yaml con el siguiente contenido

# App/config/packages/fos.yaml

fos_user:
    db_driver: orm # other valid values are 'mongodb' and 'couchdb'
    firewall_name: main
    user_class: App\Entity\Usuario
    from_email:
        address: "mailer@yourdomain.com"
        sender_name: "John Doe"

Al intentar volver a realizar la instalación nos encontramos con un nuevo mensaje de error:

The service "fos_user.resetting.controller" has a dependency on a non-existent service "templating"

Para resolver dicho mensaje, agregaremos las siguientes lineas al archivo que acabamos de crear App/config/packages/fos.yaml:

# App/config/packages/fos.yaml
framework:
    templating:
        engines: ['twig']

luego de eso pueden intentar volver a instalar FOSUserBundle mediante composer:

$ composer require friendsofsymfony/user-bundle "~2.0"
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Generating autoload files
ocramius/package-versions:  Generating version class...
ocramius/package-versions: ...done generating version class
Executing script cache:clear [OK]
Executing script assets:install --symlink --relative public [OK]

Listo!, ya tienen FOSUserBundle instalado.

Configuración de FOSUserBundle

Una vez instalado FOSUserBundle lo siguiente será configurarlo:

Configurar la clase de usuario

Ahora vamos a crear la clase que controlará los usuarios, la crearemos mediante Doctrine:

$ php bin/console make:entity

 Class name of the entity to create or update (e.g. GrumpyPizza):
 > Usuario

 created: src/Entity/Usuario.php
 created: src/Repository/UsuarioRepository.php
 
 Entity generated! Now let's add some fields!
 You can always add more fields later manually or by re-running this command.

 New property name (press <return> to stop adding fields):
 > nombre

 Field type (enter ? to see all types) [string]:
 > 

 Field length [255]:
 > 

 Can this field be null in the database (nullable) (yes/no) [no]:
 > yes

 updated: src/Entity/Usuario.php

 Add another property? Enter the property name (or press <return> to stop adding fields):
 > 


           
  Success! 
           

 Next: When you're ready, create a migration with make:migration

Ahora debemos personalizar la clase que acabamos de crear App/Src/Entity/usuario.php

<?php

namespace App\Entity;

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

/**
 * @ORM\Entity(repositoryClass="App\Repository\UsuarioRepository")
 */
class Usuario extends BaseUser
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $nombre;

    public function getId()
    {
        return $this->id;
    }

    public function getNombre(): ?string
    {
        return $this->nombre;
    }

    public function setNombre(?string $nombre): self
    {
        $this->nombre = $nombre;

        return $this;
    }

    public function __construct()
    {
        parent::__construct();
        // your own logic
    }
}

Importante: La clase Usuario debe ser heredada de BaseUser, asimismo la clase Usuario debe ser la misma declarada en el archivo App/config/packages/fos.yaml mediante la etiqueta user_class: App\Entity\Usuario como se ha hecho anteriormente.

Importante: El campo $id debe ser declarado protected, de lo contrario encontraremos el siguiente error:

Compile Error: Access level to App\Entity\Usuario::$id must be protected (as in class FOS\UserBundle  
  \Model\User) or weaker

Importante: Notar que el campo $nombre ha sido declarado nullable=true

Luego de eso actualizaremos el esquema de la base de datos usando Doctrine:

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

Seguridad

Lo siguiente es configurar los accesos de la aplicación, esto se hace modificando el archivo App/config/packages/security.yaml

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

            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 }

Ruteo

Se tiene que especificar cuales son las rutas que utilizará FOSUserBundle para las distintas páginas que contiene, para ello modificaremos el archivo App/config/routes.yaml

# App/config/routes.yaml
fos_user:
    resource: "@FOSUserBundle/Resources/config/routing/all.xml"

Traducción

Para utilizar los mensajes por defecto del bundle se debe agregar las siguientes lineas en nuestro archivo de configuración App/config/packages/fos.yaml

#App/config/packages/fos.yaml
framework:
    translator: ~

Para fijar el idioma español debemos configurar lo siguiente en el archivo /App/config/package/traslation.yaml

#App/config/packages/traslation.yaml
framework:
    default_locale: 'es'

Comentarios finales

Habiendo configurado todo lo anterior ya podemos ejecutar nuestro sitio para registrar un usuario.

$ php bin/console server:run
                                                                                                         
 [OK] Server listening on http://127.0.0.1:8000

Para crear nuevos usuarios en nuestro sitio lo podemos hacer en la siguiente ruta:

http://127.0.0.1:8000/register

Y para iniciar sesión en el sitio debemos ir a la siguiente dirección:

http://127.0.0.1:8000/login

About: kevinuni


One thought on “Tutorial para instalar FOSUserBundle en Symfony4”

Agregue un comentario

Su dirección de correo no se hará público. Los campos requeridos están marcados *