Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Más configuración de form_login

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

Utilizar form_login no es tan flexible como una clase de autentificador personalizada... aunque se pueden configurar muchas cosas.

Por ejemplo, ahora mismo, no comprueba nuestro token CSRF. Habilita eso diciendo enable_csrf: true:

security:
... lines 2 - 16
firewalls:
... lines 18 - 20
main:
... lines 22 - 24
form_login:
... lines 26 - 29
enable_csrf: true
... lines 31 - 54

¡Eso es! En las opciones, cuando activas la protección CSRF, busca un campo oculto llamado _csrf_token con la cadena authenticate utilizada para generarlo. Afortunadamente, en nuestra plantilla, ya estamos utilizando ambas cosas... así que esto va a funcionar.

Ver la lista completa de opciones

Y hay aún más formas de configurarlo. Recuerda: para obtener esta configuración, he ejecutado debug:config security... que muestra tu configuración actual, incluyendo los valores por defecto. Pero aquí no se muestran todas las opciones. Para ver una lista completa, ejecutaconfig:dump security.

symfony console config:dump security

En lugar de mostrar tu configuración actual, esto muestra una enorme lista de configuraciones de ejemplo. Esta es una lista mucho más grande... aquí está form_login. Mucho de esto lo hemos visto antes... pero success_handler y failure_handler son nuevos. Puedes buscarlos en la documentación para aprender a controlar lo que ocurre tras el éxito o el fracaso.

Pero también, más adelante, vamos a conocer una forma más global de engancharse al proceso de éxito o fracaso registrando un oyente de eventos.

Renderización de "último_nombre_de_usuario" en el formulario de inicio de sesión

De todos modos, ya no vamos a utilizar nuestro LoginFormAuthenticator, así que puedes eliminarlo.

Y... ¡Tengo buenas noticias! ¡El autentificador principal está haciendo una cosa que nuestra clase nunca hizo! En authenticate()... llama a getCredentials() para leer los datos POST. Déjame buscar "sesión"... ¡yup! Esto me llevó agetCredentials(). De todos modos, después de coger el correo electrónico enviado - en este código que se almacena como $credentials['username'] - guarda ese valor en la sesión.

Lo hace para que, si falla la autenticación, podamos leerlo y rellenar previamente la casilla del correo electrónico en el formulario de acceso.

¡Vamos a hacerlo! Ve a nuestro controlador: src/Controller/SecurityController.php. EsteAuthenticationUtils tiene otro método útil. Pasa una nueva variable a la plantilla llamada last_username -puedes llamarla last_email si quieres- y ponla en $authenticationUtils->getLastUsername():

... lines 1 - 9
class SecurityController extends AbstractController
{
... lines 12 - 14
public function login(AuthenticationUtils $authenticationUtils): Response
{
return $this->render('security/login.html.twig', [
... line 18
'last_username' => $authenticationUtils->getLastUsername(),
]);
}
... lines 22 - 29
}

Una vez más, esto es sólo un ayudante para leer una clave específica de la sesión.

Ahora, en la plantilla - login.html.twig - aquí arriba en el campo de correo electrónico, añadevalue="{{ last_username }} ":

... lines 1 - 4
{% block body %}
<div class="container">
<div class="row">
<div class="login-form bg-light mt-4 p-4">
<form method="post" class="row g-3">
... lines 10 - 15
<div class="col-12">
... line 17
<input type="email" name="email" id="inputEmail" class="form-control" value="{{ last_username }}" required autofocus>
</div>
... lines 20 - 33
</form>
</div>
</div>
</div>
{% endblock %}

¡Genial! Si vamos a /login... ¡ya está ahí por haber rellenado el formulario hace un minuto! Si introducimos un correo electrónico diferente... ¡sí! Eso también se pega.

A continuación: volvamos a la autorización aprendiendo a denegar el acceso en un controlador... de varias maneras.

Leave a comment!

4
Login or Register to join the conversation

how can we implement this if we kept using the old loginFormAuthonticator on the onAuthenticationFailure method?

Reply

Hey @Soufiyane!

Are you referring to how to print the "last username" thing? If so, the 2 steps are:

1) In your custom authenticator, in authenticate(), after reading the email, call:

$request->getSession()->set(SecurityRequestAttributes::LAST_USERNAME, $credentials['username']);

2) In your controller, read that value in the same way as see in this chapter :).

Let me know if that helps!

Cheers!

Reply
Lechu85 Avatar
Lechu85 Avatar Lechu85 | posted hace 1 año | edited

Hi. I stayed with the custom login in my project. Can you show me how to add $authenticationUtils-> getLastUsername(), in this case? In case without form_login: it didn't work :)

Reply

Hey Leszek,

You only need to inject the service Symfony\Component\Security\Http\Authentication\AuthenticationUtils into your Controller's method, or in case you need it in your authenticator, you can add another argument constructor and inject it there

Cheers!

1 Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

¡Este tutorial también funciona muy bien para Symfony 6!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=8.1",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "babdev/pagerfanta-bundle": "^3.3", // v3.3.0
        "composer/package-versions-deprecated": "^1.11", // 1.11.99.4
        "doctrine/annotations": "^1.0", // 1.13.2
        "doctrine/doctrine-bundle": "^2.1", // 2.6.3
        "doctrine/doctrine-migrations-bundle": "^3.0", // 3.1.1
        "doctrine/orm": "^2.7", // 2.10.1
        "knplabs/knp-markdown-bundle": "^1.8", // 1.9.0
        "knplabs/knp-time-bundle": "^1.11", // v1.16.1
        "pagerfanta/doctrine-orm-adapter": "^3.3", // v3.3.0
        "pagerfanta/twig": "^3.3", // v3.3.0
        "phpdocumentor/reflection-docblock": "^5.2", // 5.2.2
        "scheb/2fa-bundle": "^5.12", // v5.12.1
        "scheb/2fa-qr-code": "^5.12", // v5.12.1
        "scheb/2fa-totp": "^5.12", // v5.12.1
        "sensio/framework-extra-bundle": "^6.0", // v6.2.0
        "stof/doctrine-extensions-bundle": "^1.4", // v1.6.0
        "symfony/asset": "5.3.*", // v5.3.4
        "symfony/console": "5.3.*", // v5.3.7
        "symfony/dotenv": "5.3.*", // v5.3.8
        "symfony/flex": "^1.3.1", // v1.17.5
        "symfony/form": "5.3.*", // v5.3.8
        "symfony/framework-bundle": "5.3.*", // v5.3.8
        "symfony/monolog-bundle": "^3.0", // v3.7.0
        "symfony/property-access": "5.3.*", // v5.3.8
        "symfony/property-info": "5.3.*", // v5.3.8
        "symfony/rate-limiter": "5.3.*", // v5.3.4
        "symfony/runtime": "5.3.*", // v5.3.4
        "symfony/security-bundle": "5.3.*", // v5.3.8
        "symfony/serializer": "5.3.*", // v5.3.8
        "symfony/stopwatch": "5.3.*", // v5.3.4
        "symfony/twig-bundle": "5.3.*", // v5.3.4
        "symfony/ux-chartjs": "^1.3", // v1.3.0
        "symfony/validator": "5.3.*", // v5.3.8
        "symfony/webpack-encore-bundle": "^1.7", // v1.12.0
        "symfony/yaml": "5.3.*", // v5.3.6
        "symfonycasts/verify-email-bundle": "^1.5", // v1.5.0
        "twig/extra-bundle": "^2.12|^3.0", // v3.3.3
        "twig/string-extra": "^3.3", // v3.3.3
        "twig/twig": "^2.12|^3.0" // v3.3.3
    },
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.3", // 3.4.0
        "symfony/debug-bundle": "5.3.*", // v5.3.4
        "symfony/maker-bundle": "^1.15", // v1.34.0
        "symfony/var-dumper": "5.3.*", // v5.3.8
        "symfony/web-profiler-bundle": "5.3.*", // v5.3.8
        "zenstruck/foundry": "^1.1" // v1.13.3
    }
}
userVoice