Symfony Shorty | Benutzer Prüfung

Der einfach Login in Symfony ist mit dem Security Bundle relativ schnell umgesetzt. Der Login funktioniert und die Passwort vergessen Funktion auch – nun ist es an der Zeit sich mit Double Opt-In und anderen Datenschutz Dingen auseinander zu setzen.

UserCheckerInterface

Zum Glück hat hier Symfony bereit ein Interface dafür – das UserCheckerInterface. Das löst das bisher bekannte AdvancedUserInterface ab – in welchem bisher so etwas wie isEnabled() etc. geprüft wurde. Damit könnt Ihr vor und nach der Authentifizierung zusätzliche Parameter prüfen (checkPreAuth / checkPostAuth).

Die ausführliche englische Doku findet Ihr wie immer direkt in der Symfony Dokumentation (4.3 oder 3.4).

Use Case

In meinem Fall möchte ich nicht autorisierte Benutzer Registrierungen verhindern. Dafür habe ich ein active Flag in die UserEntity eingebunden, welches Standardmäßig auf 0/false gesetzt ist. Erst wenn der Benutzer den Link in der E-Mail klickt, wird der Account aktiv geschaltet. Pretty basic, wird aber oft bei kleinen Projekten vergessen.

src/Security/UserChecker.php

<?php

namespace App\Security;

use Symfony\Component\Security\Core\Exception\DisabledException;
use Symfony\Component\Security\Core\User\UserCheckerInterface;
use Symfony\Component\Security\Core\User\UserInterface;

class UserChecker implements UserCheckerInterface
{

    public function checkPreAuth(UserInterface $user)
    {
        if ($user->isActive()) {
            return;
        } else {
            throw new DisabledException('Bitte bestätige das per E-Mail versandte Double Opt-In');
        }
    }

    public function checkPostAuth(UserInterface $user)
    {
        // Do stuff here
    }
}

config/packages/security.yaml

firewalls:
        main:
            pattern: ^/
            user_checker: App\Security\UserChecker

Übersetzung

Nicht wundern, warum die Nachricht nicht angezeigt wird, obwohl du diese in der DisabledException() übergeben hast. Das liegt an der Standard Generierung im Twig Template:

{% if error %}
        <div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
    {% endif %}

Einige Stackoverflow Beiträge raten hier dies einfach mit:

<div class="alert alert-danger">{{ error.message|trans({},'messages') }}</div>

zu ersetzen.

Aber VORSICHT, das führt dazu, dass bei allen anderen Exceptions nun der genaue Error Text erscheint und keine Standard Übersetzung aus Symfony:

Authentication failed because App\Security\LoginFormAuthenticator::checkCredentials() did not return true.

Nutze stattdessen dafür am besten die CustomUserMessageAuthenticationException()

throw new CustomUserMessageAuthenticationException(
                'Account inaktiv. Du solltest bereits eine Aktivierungsmail erhalten haben.'
            );

Ergebnis

Pre Validierung bei Login

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert