Personalizzare il form di login

L’uso di un form di login per l’autenticazione è un metodo comune e flessibile per gestire l’autenticazione in Symfony. Quasi ogni aspetto del form è personalizzabile. La configurazione predefinita e completa è mostrata nella prossima sezione.

Riferimento di configurazione del form di login

Per il riferimento completo della configurazione del form di login, vedere Riferimento configurazione sicurezza. Alcune delle opzioni più interessanti sono spiegate di seguito.

Rinvio dopo il successo

Si può modificare il posto in cui il form di login rinvia dopo un login eseguito con successo, usando le varie opzioni di configurazione. Per impostazione predefinita, il form rinvierà all’URL richiesto dall’utente (cioè l’URL che ha portato al form di login). Per esempio, se l’utente ha richiesto http://www.example.com/admin/post/18/edit, sarà successivamente rimandato indietro a http://www.example.com/admin/post/18/edit, dopo il login. Questo grazie alla memorizzazione in sessione dell’URL richiesto. Se non c’è alcun URL in sessione (forse l’utente ha richiesto direttamente la pagina di login), l’utente è rinviato alla pagina predefinita, che è / (ovvero la homepage). Si può modificare questo comportamento in diversi modi.

Nota

Come accennato, l’utente viene rinviato alla pagina che ha precedentemente richiesto. A volte questo può causare problemi, per esempio se una richiesta AJAX eseguita in background appare come ultimo URL visitato, rinviando quindi l’utente in quell’URL. Per informazioni su come controllare questo comportamento, vedere Cambiare il comportamento del percorso di rinvio predefinito.

Cambiare la pagina predefinita

Prima di tutto, la pagina predefinita (la pagina a cui l’utente viene rinviato, se non ci sono pagine precedenti in sessione) può essere impostata. Per impostarla alla rotta default_security_target, usare la seguente configurazione:

  • 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',
                ),
            ),
        ),
    ));
    

Ora, se non ci sono URL in sessione, gli utenti saranno rimandati alla rotta default_security_target.

Rinviare sempre alla pagina predefinita

Si può fare in modo che gli utenti siano sempre rinviati alla pagina predefinita, senza considerare l’URL richiesta prima del login, impostando l’opzione 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,
                ),
            ),
        ),
    ));
    

Usare l’URL del referer

Se nessun URL è stato memorizzato in sessione, si potrebbe voler provare a usare HTTP_REFERER, che spesso coincide. Lo si può fare impostando use_referer a true (il valore predefinito è 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,
                ),
            ),
        ),
    ));
    

Controllare l’URL di rinvio da dentro un form

Si può anche forzare la pagina di rinvio dell’utente nel form stesso, includendo un campo nascosto dal nome _target_path. Per esempio, per rinviare all’URL definito in una rotta account, fare come segue:

  • 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="account" />
    
        <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">Nome utente:</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="account" />
    
        <input type="submit" name="login" />
    </form>
    

L’utente sarà ora rinviato al valore del campo nascosto. Il valore può essere un percorso relativo, un URL assoluto o un nome di rotta. Si può anche modificare il nome del campo nascosto, cambiando l’opzione target_path_parameter con il valore desiderato.

  • 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,
                ),
            ),
        ),
    ));
    

Rinvio al fallimento del login

Oltre a rinviare l’utente dopo un login eseguito con successo, si può anche impostare l’URL a cui l’utente va rinviato dopo un login fallito (p.e. perché è stato inserito un nome utente o una password non validi). Per impostazione predefinita, l’utente viene rinviato al medesimo form di login. Si può impostare un URL diverso, usando la configurazione seguente:

  • 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',
                ),
            ),
        ),
    ));