Cómo personalizar el formulario de acceso

Usar un formulario de acceso para autenticación es un método común y flexible para gestionar la autenticación en Symfony2. Casi todos los aspectos del formulario de acceso se pueden personalizar. La configuración predeterminada completa se muestra en la siguiente sección.

Referencia de configuración del formulario de acceso

Para ver la referencia de la configuración del formulario de acceso completa, consulta la Referencia de configuración de Security. Algunas de las opciones más interesantes se explican a continuación.

Redirigiendo después del ingreso

Puedes cambiar el lugar al cual el formulario de acceso redirige después de un inicio de sesión satisfactorio utilizando diferentes opciones de configuración. Por omisión, el formulario redirigirá a la URL que el usuario solicitó (por ejemplo, la URL que provocó la exhibición del formulario de acceso). Por ejemplo, si el usuario solicitó http://www.example.com/admin/post/18/edit, entonces después de que inicie sesión, eventualmente sera llevada a http://www.example.com/admin/post/18/edit. Esto se consigue almacenando en la sesión la URL solicitada. Si no hay presente una URL en la sesión (tal vez el usuario se dirigió directamente a la página de inicio de sesión), entonces el usuario es redirigido a la página predeterminada, la cual es / (es decir, la página predeterminada del formulario de acceso). Puedes cambiar este comportamiento de varias maneras.

Nota

Como se ha mencionado, por omisión el usuario es redirigido a la página que solicitó originalmente. A veces, esto puede causar problemas, como si una petición en segundo plano de AJAX «pareciera» ser la última URL visitada, causando que el usuario sea redirigido allí. Para información sobre cómo controlar este comportamiento, consulta Cómo cambiar el comportamiento predeterminado de la ruta destino.

Cambiando la página predeterminada

En primer lugar, la página predeterminada se puede configurar (es decir, la página a la cual el usuario es redirigido si no se almacenó una página previa en la sesión). To set it to the default_security_target route use the following config:

  • YAML
    # app/config/security.yml
    security:
        firewalls:
            main:
                form_login:
                    # ...
                    default_target_path: default_security_target
    
  • XML
    <!-- app/config/security.xml -->
    <config>
        <firewall>
            <form-login
                default_target_path="default_security_target"
            />
        </firewall>
    </config>
    
  • PHP
    // app/config/security.php
    $container->loadFromExtension('security', array(
        'firewalls' => array(
            'main' => array(
                // ...
    
                'form_login' => array(
                    // ...
                    'default_target_path' => 'default_security_target',
                ),
            ),
        ),
    ));
    

Now, when no URL is set in the session, users will be sent to the default_security_target route.

Redirigiendo siempre a la página predeterminada

Puedes hacer que los usuarios siempre sean redirigidos a la página predeterminada, independientemente de la URL que hayan solicitado con anterioridad, estableciendo la opción always_use_default_target_path a true:

  • YAML
    # app/config/security.yml
    security:
        firewalls:
            main:
                form_login:
                    # ...
                    always_use_default_target_path: true
    
  • XML
    <!-- app/config/security.xml -->
    <config>
        <firewall>
            <form-login
                always_use_default_target_path="true"
            />
        </firewall>
    </config>
    
  • PHP
    // app/config/security.php
    $container->loadFromExtension('security', array(
        'firewalls' => array(
            'main' => array(
                // ...
    
                'form_login' => array(
                    // ...
                    'always_use_default_target_path' => true,
                ),
            ),
        ),
    ));
    

Utilizando la URL referente

En caso de no haber almacenado una URL anterior en la sesión, posiblemente desees intentar usar el HTTP_REFERER en su lugar, ya que a menudo será el mismo. Lo puedes hacer estableciendo use_referer a true (el valor predefinido es false):

  • YAML
    # app/config/security.yml
    security:
        firewalls:
            main:
                form_login:
                    # ...
                    use_referer:        true
    
  • XML
    <!-- app/config/security.xml -->
    <config>
        <firewall>
            <form-login
                use_referer="true"
            />
        </firewall>
    </config>
    
  • PHP
    // app/config/security.php
    $container->loadFromExtension('security', array(
        'firewalls' => array(
            'main' => array(
                // ...
    
                'form_login' => array(
                    // ...
                    'use_referer' => true,
                ),
            ),
        ),
    ));
    

Nuevo en la versión 2.1: A partir de 2.1, si la referencia es igual a la opción login_path, el usuario será redirigido a default_target_path.

Controlando la URL a redirigir desde el interior del formulario

También puedes sustituir a dónde es redirigido el usuario a través del formulario en sí mismo incluyendo un campo oculto con el nombre _target_path. Por ejemplo, para redirigir a la URL definida por alguna ruta cuenta, usa lo siguiente:

  • Twig
    {# src/Acme/SecurityBundle/Resources/views/Security/login.html.twig #}
    {% if error %}
        <div>{{ error.message }}</div>
    {% endif %}
    
    <form action="{{ path('login_check') }}" method="post">
        <label for="username">Username:</label>
        <input type="text" id="username" name="_username" value="{{ last_username }}" />
    
        <label for="password">Password:</label>
        <input type="password" id="password" name="_password" />
    
        <input type="hidden" name="_target_path" value="cuenta" />
    
        <input type="submit" name="login" />
    </form>
    
  • PHP
    <!-- src/Acme/SecurityBundle/Resources/views/Security/login.html.php -->
    <?php if ($error): ?>
        <div><?php echo $error->getMessage() ?></div>
    <?php endif; ?>
    
    <form action="<?php echo $view['router']->generate('login_check') ?>" method="post">
        <label for="username">Username:</label>
        <input type="text" id="username" name="_username" value="<?php echo $last_username ?>" />
    
        <label for="password">Password:</label>
        <input type="password" id="password" name="_password" />
    
        <input type="hidden" name="_target_path" value="cuenta" />
    
        <input type="submit" name="login" />
    </form>
    

Ahora, el usuario será redirigido al valor del campo oculto del formulario. El valor del atributo puede ser una ruta relativa, una URL absoluta, o un nombre de ruta. Incluso, puedes cambiar el nombre del campo oculto en el formulario cambiando la opción target_path_parameter a otro valor.

  • YAML
    # app/config/security.yml
    security:
        firewalls:
            main:
                form_login:
                    target_path_parameter: redirect_url
    
  • XML
    <!-- app/config/security.xml -->
    <config>
        <firewall>
            <form-login
                target_path_parameter="redirect_url"
            />
        </firewall>
    </config>
    
  • PHP
    // app/config/security.php
    $container->loadFromExtension('security', array(
        'firewalls' => array(
            'main' => array(
                'form_login' => array(
                    'target_path_parameter' => redirect_url,
                ),
            ),
        ),
    ));
    

Redirigiendo en ingreso fallido

Además de redirigir al usuario después de un inicio de sesión exitoso, también puedes definir la URL a que el usuario será redirigido después de un ingreso fallido (por ejemplo, si presentó un nombre de usuario o contraseña no válidos). Por omisión, el usuario es dirigido de nuevo al formulario de acceso. You can set this to a different route (e.g. login_failure) with the following config:

  • YAML
    # app/config/security.yml
    security:
        firewalls:
            main:
                form_login:
                    # ...
                    failure_path: login_failure
    
  • XML
    <!-- app/config/security.xml -->
    <config>
        <firewall>
            <form-login
                failure_path="login_failure"
            />
        </firewall>
    </config>
    
  • PHP
    // app/config/security.php
    $container->loadFromExtension('security', array(
        'firewalls' => array(
            'main' => array(
                // ...
    
                'form_login' => array(
                    // ...
                    'failure_path' => 'login_failure',
                ),
            ),
        ),
    ));
    
Bifúrcame en GitHub