Automatisk etterregistrering brukerautentisering

stemmer
101

Vi bygger en virksomhet app fra bunnen av i Symfony 2, og jeg har kjørt inn i en bit av en ulempe med brukerregistrering flow: etter at brukeren oppretter en konto, bør de automatisk logget på med disse legitimasjon, i stedet for å bli umiddelbart tvunget til å gi sine akkreditiver igjen.

Noen hadde noen erfaring med dette, eller i stand til å peke meg i riktig retning?

Publisert på 04/05/2011 klokken 16:31
kilden bruker
På andre språk...                            


8 svar

stemmer
126

Symfony 4,0

Denne prosessen has not endret fra symfony 3-4, men her er et eksempel med den nylig anbefalte AbstractController. Både security.token_storageog sessiontjenester er registrert i den overordnede getSubscribedServicesmetoden slik at du slipper å legge de i kontrolleren.

use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use YourNameSpace\UserBundle\Entity\User;

class LoginController extends AbstractController{

    public function registerAction()
    {    
        $user = //Handle getting or creating the user entity likely with a posted form
        $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
        $this->container->get('security.token_storage')->setToken($token);
        $this->container->get('session')->set('_security_main', serialize($token));
        // The user is now logged in, you can redirect or do whatever.
    }

}

Symfony 2.6.x - Symfony 3.0.x

Per symfony 2.6 security.contexter foreldet i favør av security.token_storage. Kontrolleren kan nå bare være:

use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use YourNameSpace\UserBundle\Entity\User;

class LoginController extends Controller{

    public function registerAction()
    {    
        $user = //Handle getting or creating the user entity likely with a posted form
        $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
        $this->get('security.token_storage')->setToken($token);
        $this->get('session')->set('_security_main', serialize($token));
    }

}

Selv om dette er foreldet kan du fortsatt bruke security.contextsom det har blitt gjort for å være bakoverkompatibel. Bare vær klar til å oppdatere den for Symfony 3

Du kan lese mer om 2.6 endringene for sikkerhet her: https://github.com/symfony/symfony/blob/2.6/UPGRADE-2.6.md

Symfony 2.3.x

For å oppnå dette i symfony 2.3 kan du ikke lenger bare sette token i sikkerhetskonteksten. Du trenger også å lagre token til økten.

Forutsatt en sikkerhets fil med en brannmur som:

// app/config/security.yml
security:
    firewalls:
        main:
            //firewall settings here

Og en kontroller handling lignende også:

use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use YourNameSpace\UserBundle\Entity\User;

class LoginController extends Controller{

    public function registerAction()
    {    
        $user = //Handle getting or creating the user entity likely with a posted form
        $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
        $this->get('security.context')->setToken($token);
        $this->get('session')->set('_security_main',serialize($token));
        //Now you can redirect where ever you need and the user will be logged in
    }

}

For token etableringen vil du ønsker å opprette en UsernamePasswordToken, Dette godtar 4 parametere: brukerenhet, brukerlegitimasjon, brannmur navn, brukerroller. Du ikke trenger å gi brukeren legitimasjon for token skal være gyldig.

Im ikke 100% sikker på at du setter symbolet på security.contexter nødvendig hvis du bare kommer til å omdirigere en gang. Men det ser ikke ut til å skade, så jeg har forlatt den.

Så viktig del, sette økten variabel. Variablene navnekonvensjon er _security_etterfulgt av brannmuren navn, i dette tilfellet mainå gjøre_security_main

Svarte 24/10/2013 kl. 23:42
kilden bruker

stemmer
63

Skjønte dette ut, endelig.

Etter brukerregistrering, bør du ha tilgang til et objekt instanceof hva du har angitt som brukerenhet i din leverandør konfigurasjon. Løsningen er å skape et nytt token med at brukerenhet og passerer den inn i sikkerhetskonteksten. Her er et eksempel basert på mitt oppsett:

RegistrationController.php:

$token = new UsernamePasswordToken($userEntity, null, 'main', array('ROLE_USER'));
$this->get('security.context')->setToken($token);

Hvor mainer navnet på brannmuren for din søknad (takk, @Joe). Det er egentlig alt som skal til; systemet vurderer nå bruker fullt logget inn som brukeren de nettopp har opprettet.

EDIT: Per @ Miquel kommentar, har jeg oppdatert kontrolleren kodeeksempel for å inkludere en fornuftig standard rolle for en ny bruker (men selvsagt dette kan justeres i henhold til programmets spesifikke behov).

Svarte 10/05/2011 kl. 22:52
kilden bruker

stemmer
6

Jeg bruker Symfony 2,2 og min erfaring var litt annerledes enn Problematisk er , så dette er en kombinert versjon av all info fra dette spørsmålet, pluss noen av mine egne.

Jeg tror Joe er galt om verdien av $providerKeyden tredje parameter til UsernamePasswordTokenkonstruktøren. Det er ment å være nøkkelen til en godkjennings (ikke bruker) leverandør. Det er brukt ved autentiseringssystem for å skille mellom symboler som er opprettet mellom forskjellige leverandører. Enhver leverandør som stammer fra UserAuthenticationProvidervil bare autentisere tokens som leverandør nøkkelen passer sine egne. For eksempel, de UsernamePasswordFormAuthenticationListenersetter nøkkelen token skaper det å tilpasse det til sin tilsvarende DaoAuthenticationProvider. Som lar en enkelt brannmur har flere brukernavn + passord leverandører uten dem tråkke på hverandre. Vi må derfor velge en nøkkel som ikke vil komme i konflikt med andre leverandører. Jeg bruker 'new_user'.

Jeg har noen systemer i andre deler av min søknad som er avhengig av godkjenning suksess arrangementet , og som ikke er avfyrt ved bare å sette token av sammenhengen. Jeg måtte få EventDispatcherfra beholderen og brann hendelsen manuelt. Jeg besluttet mot også å skyte en interaktiv pålogging arrangement fordi vi autentisere brukeren implisitt, ikke som svar på en eksplisitt påloggingsforespørselen.

use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\AuthenticationEvents;
use Symfony\Component\Security\Core\Event\AuthenticationEvent;

$user = // get a Symfony user instance somehow
$token = new UsernamePasswordToken(
        $user, null, 'new_user', $user->getRoles() );
$this->get( 'security.context' )->setToken( $token );
$this->get( 'event_dispatcher' )->dispatch(
        AuthenticationEvents::AUTHENTICATION_SUCCESS,
        new AuthenticationEvent( $token ) );

Legg merke til at bruk av $this->get( .. )antar biten er i en styreenhet metode. Hvis du bruker koden et annet sted må du endre dem til å ringe ContainerInterface::get( ... )på en måte som passer til miljøet. Som det skjer mine brukerenheter implementere UserInterfaceslik at jeg kan bruke dem direkte med token. Hvis din ikke du må finne en måte å konvertere dem til UserInterfacetilfeller.

At koden fungerer, men jeg føler at det er hacking rundt Symfony autentiserings arkitektur heller enn å jobbe med det. Det ville trolig være mer riktig å gjennomføre en ny autentisering leverandør med sin egen token klasse i stedet for å kapre den UsernamePasswordToken. Også ved hjelp av en skikkelig leverandør ville bety at hendelsene ble håndtert for deg.

Svarte 04/06/2013 kl. 03:06
kilden bruker

stemmer
6

Hvis du har et brukergrensesnitt objekt (og det bør være tilfelle mesteparten av tiden) vil du kanskje bruke getRoles fungere som den implementerer for det siste argumentet. Så hvis du oppretter en funksjon logUser, bør det ser ut som at:

public function logUser(UserInterface $user) {
    $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
    $this->container->get('security.context')->setToken($token);
}
Svarte 23/04/2012 kl. 21:53
kilden bruker

stemmer
4

I tilfelle noen har samme oppfølgings spørsmålet som holdt meg å komme tilbake til her:

ringe

$this->container->get('security.context')->setToken($token); 

bare effekter gjeldende security.contextfor ruten brukt.

Dvs. du kan bare logge på en bruker fra en url innenfor brannmuren kontroll.

(Legg til et unntak for ruten om nødvendig - IS_AUTHENTICATED_ANONYMOUSLY)

Svarte 04/09/2012 kl. 01:17
kilden bruker

stemmer
2

Jeg prøvde alle svarene her, og ingen virket. Den eneste måten jeg kunne godkjenne brukerne mine på en kontroller er ved å lage en subrequest og deretter omdirigere. Her er min kode, jeg bruker Silex men du kan enkelt tilpasse den til symfony2:

$subRequest = Request::create($app['url_generator']->generate('login_check'), 'POST', array('_username' => $email, '_password' => $password, $request->cookies->all(), array(), $request->server->all());

$response = $app->handle($subRequest, HttpKernelInterface::MASTER_REQUEST, false);

return $app->redirect($app['url_generator']->generate('curriculos.editar'));
Svarte 03/09/2013 kl. 10:36
kilden bruker

stemmer
2

Som problematisk her allerede nevnt, er dette unnvikende $ providerKey parameter i realiteten ikke noe mer enn navnet på brannmurregelen 'foobar' i tilfelle av eksempelet nedenfor.

firewalls:
    foobar:
        pattern:    /foo/
Svarte 17/04/2012 kl. 06:15
kilden bruker

stemmer
0

På Symfony versjon 2.8.11 (sannsynligvis jobbe for eldre og nyere versjoner), hvis du bruker FOSUserBundle bare gjøre dette:

try {
    $this->container->get('fos_user.security.login_manager')->loginUser(
    $this->container->getParameter('fos_user.firewall_name'), $user, null);
} catch (AccountStatusException $ex) {
    // We simply do not authenticate users which do not pass the user
    // checker (not enabled, expired, etc.).
}

Du trenger ikke å sende hendelsen som jeg har sett på andre løsninger.

inpired fra FOS \ UserBundle \ Controller \ RegistrationController :: authenticateUser

(Fra composer.json FOSUserBundle versjon: "friendsofsymfony / bruker-bundle": "~ 1.3")

Svarte 06/06/2017 kl. 09:42
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more