php - symfony 4 user roles




Autenticação de usuário pós-registro automático (6)

Como problemático aqui já mencionado, este parâmetro $ providerKey indescritível não é na realidade nada mais que o nome da sua regra de firewall, 'foobar' no caso do exemplo abaixo.

firewalls:
    foobar:
        pattern:    /foo/

Estamos construindo um aplicativo de negócios a partir do zero no Symfony 2, e eu me deparo com um obstáculo com o fluxo de registro do usuário: depois que o usuário cria uma conta, ele deve estar automaticamente logado com essas credenciais, de ser imediatamente forçado a fornecer suas credenciais novamente.

Alguém teve alguma experiência com isso, ou capaz de me apontar na direção certa?


Descobri isso finalmente.

Após o registro do usuário, você deve ter acesso a uma instância de objeto do que você definiu como sua entidade de usuário na configuração do provedor. A solução é criar um novo token com essa entidade de usuário e passá-lo para o contexto de segurança. Aqui está um exemplo baseado na minha configuração:

RegistrationController.php:

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

Onde main é o nome do firewall da sua aplicação (obrigado, @Joe). Isso é realmente tudo que existe para isso; O sistema agora considera seu usuário totalmente logado como o usuário que acabou de criar.

EDIT: Por @ Miquel comentário, eu atualizei o exemplo de código do controlador para incluir uma função padrão sensata para um novo usuário (embora, obviamente, isso pode ser ajustado de acordo com as necessidades específicas do aplicativo).


Eu tentei todas as respostas aqui e nenhuma funcionou. A única maneira de autenticar meus usuários em um controlador é fazer uma subrequest e, em seguida, redirecionar. Aqui está o meu código, estou usando o silex, mas você pode adaptá-lo facilmente ao 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'));

No Symfony versão 2.8.11 (provavelmente funcionando para versões mais antigas e mais recentes), se você usar o FOSUserBundle, simplesmente faça o seguinte:

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.).
}

Não há necessidade de despachar evento como já vi em outras soluções.

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

(do composer.json versão do FOSUserBundle: "friendsofsymfony / user-bundle": "~ 1.3")


Se você tiver um objeto UserInterface (e esse deve ser o caso na maioria das vezes), talvez você queira usar a função getRoles implementada para o último argumento. Então, se você criar uma função logUser, ela deve se parecer com isso:

public function logUser(UserInterface $user) {
    $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
    $this->container->get('security.context')->setToken($token);
}

Symfony 4.0

Este processo não mudou do symfony 3 para 4, mas aqui está um exemplo usando o AbstractController recém-recomendado. Os serviços security.token_storage e session são registrados no método getSubscribedServices pai, portanto, você não precisa adicioná-los ao controlador.

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

A partir do symfony 2.6, security.context está obsoleto em favor de security.token_storage . O controlador pode agora ser simplesmente:

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));
    }

}

Embora isso esteja obsoleto, você ainda pode usar o security.context como foi feito para ser compatível com versões anteriores. Esteja pronto para atualizá-lo para o Symfony 3

Você pode ler mais sobre as mudanças 2.6 para segurança aqui: https://github.com/symfony/symfony/blob/2.6/UPGRADE-2.6.md

Symfony 2.3.x

Para realizar isso no symfony 2.3, você não pode mais apenas definir o token no contexto de segurança. Você também precisa salvar o token para a sessão.

Assumindo um arquivo de segurança com um firewall como:

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

E uma ação do controlador similar também:

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
    }

}

Para a criação do token, você desejará criar um UsernamePasswordToken . Isso aceita 4 parâmetros: Entidade do usuário, Credenciais do usuário, Nome do Firewall, Funções do usuário. Você não precisa fornecer as credenciais do usuário para que o token seja válido.

Não tenho 100% de certeza de que a configuração do token no security.context é necessária se você for redirecionar imediatamente. Mas não parece doer, então eu deixei.

Então a parte importante, definindo a variável de sessão. A convenção de nomenclatura de variáveis ​​é _security_ seguida do nome do seu firewall, neste caso, a criação main _security_main





registration