Una vez que un usuario está autenticado, normalmente sus credenciales se almacenan en la sesión. Esto significa que cuando termina la sesión esta se desechará y tendrás que proporcionar de nuevo tus datos de acceso la siguiente vez que quieras acceder a la aplicación. Puedes permitir a tus usuarios que elijan entre permanecer conectados durante más tiempo del que dure la sesión con una cookie con la opción remember_me del cortafuegos. El cortafuegos necesita tener configurada una clave secreta, la cual se utiliza para cifrar el contenido de la cookie. También tiene varias opciones con los valores predefinidos mostrados a continuación:
# app/config/security.yml
firewalls:
main:
remember_me:
key: "%secret%"
lifetime: 31536000 # 365 días en segundos
path: /
domain: ~ # El valor predeterminado es el dominio actual de $_SERVER
<!-- app/config/security.xml -->
<config>
<firewall>
<remember-me
key = "%secret%"
lifetime = "31536000" <!-- 365 días en segundos -->
path = "/"
domain = "" <!-- El valor predeterminado es el dominio actual de $_SERVER -->
/>
</firewall>
</config>
// app/config/security.php
$container->loadFromExtension('security', array(
'firewalls' => array(
'main' => array(
'remember_me' => array(
'key' => '%secret%',
'lifetime' => 31536000, // 365 days in seconds
'path' => '/',
'domain' => '', // Defaults to the current domain from $_SERVER
),
),
),
));
Es buena idea ofrecer al usuario la opción de utilizar o no la funcionalidad recuérdame, ya que no siempre es adecuada. La forma habitual de hacerlo consiste en añadir una casilla de verificación en el formulario de acceso. Al dar a la casilla de verificación el nombre _remember_me, la cookie se ajustará automáticamente cuando la casilla esté marcada y el usuario inicia sesión satisfactoriamente. Por lo tanto, tu formulario de acceso específico en última instancia, podría tener este aspecto:
{# 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="checkbox" id="remember_me" name="_remember_me" checked />
<label for="remember_me">Keep me logged in</label>
<input type="submit" name="login" />
</form>
<!-- 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="checkbox" id="remember_me" name="_remember_me" checked />
<label for="remember_me">Keep me logged in</label>
<input type="submit" name="login" />
</form>
El usuario entonces, se registra automáticamente en las subsecuentes visitas, mientras que la cookie sea válida.
Cuando el usuario vuelve a tu sitio, se autentica automáticamente en función de la información almacenada en la cookie recuérdame. Esto permite al usuario acceder a recursos protegidos como si el usuario se hubiera autenticado en realidad al visitar el sitio.
En algunos casos, sin embargo, puedes obligar al usuario a realmente volver a autenticarse antes de acceder a ciertos recursos. Por ejemplo, podrías permitir a un usuario de «recuérdame» ver la información básica de la cuenta, pero luego obligarlo a volver a autenticarse realmente antes de modificar dicha información.
El componente de seguridad proporciona una manera fácil de hacerlo. Además de los roles asignados explícitamente, a los usuarios se les asigna automáticamente uno de los siguientes roles, dependiendo de cómo se hayan autenticado:
Las puedes utilizar para controlar el acceso más allá de los roles asignados explícitamente.
Nota
Si tienes el rol IS_AUTHENTICATED_REMEMBERED, entonces también tienes el rol IS_AUTHENTICATED_ANONYMOUSLY. Si tienes el rol IS_AUTHENTICATED_FULLY, entonces también tienes los otros dos roles. En otras palabras, estos roles representan tres niveles de «fortaleza» incremental en la autenticación.
Puedes utilizar estos roles adicionales para un control más preciso sobre el acceso a ciertas partes de un sitio. Por ejemplo, posiblemente desees que el usuario pueda ver su cuenta en /cuenta cuando está autenticado por cookie, pero tiene que proporcionar sus datos de acceso para poder editar la información de la cuenta. Lo puedes hacer protegiendo acciones específicas del controlador usando estos roles. La acción de edición en el controlador se puede proteger usando el servicio Contexto.
En el siguiente ejemplo, la acción sólo es permitida si el usuario tiene el rol IS_AUTHENTICATED_FULLY.
// ...
use Symfony\Component\Security\Core\Exception\AccessDeniedException
public function editAction()
{
if (false === $this->get('security.context')->isGranted(
'IS_AUTHENTICATED_FULLY'
)) {
throw new AccessDeniedException();
}
// ...
}
También puedes optar por instalar y utilizar el opcional JMSSecurityExtraBundle, el cual puede proteger tu controlador usando anotaciones:
use JMS\SecurityExtraBundle\Annotation\Secure;
/**
* @Secure(roles="IS_AUTHENTICATED_FULLY")
*/
public function editAction($name)
{
// ...
}
Truco
Si, además, hubiera un control de acceso en tu configuración de seguridad que requiere que el usuario tenga un rol ROLE_USER a fin de acceder a cualquier área de la cuenta, entonces tendríamos la siguiente situación:
Para más información sobre proteger servicios o métodos de esta manera, consulta Cómo proteger cualquier servicio o método de tu aplicación.