programing

등록 후 사용자 자동 인증

procenter 2022. 10. 20. 21:50
반응형

등록 후 사용자 자동 인증

Symfony 2에서 비즈니스 앱을 처음부터 구축하고 있는데, 사용자 등록 흐름에 문제가 좀 있습니다. 사용자가 계정을 만든 후 자격 증명을 즉시 다시 제공하도록 강요받는 대신 해당 자격 증명으로 자동으로 로그인해야 합니다.

이 일을 경험하신 분, 아니면 저를 올바른 방향으로 인도해 주실 분?

Symfony 4.0

되지 않았지만,된 Symfony 3의 4를 .AbstractController둘 다security.token_storagesession되어 있습니다.getSubscribedServices컨트롤러에 추가하지 않아도 됩니다.

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

.6 Symfony 2.6 security.context 폐지되다security.token_storage컨트롤러는 다음과 같이 간단하게 할 수 있습니다.

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

}

은 권장되지 계속 할 수 .security.context하위 호환성을 갖도록 만들어졌기 때문입니다.Symfony 3 sym sym sym sym sym sym sym sym sym sym sym sym sym 。

시큐러티의 2.6 의 변경에 대해서는, https://github.com/symfony/symfony/blob/2.6/UPGRADE-2.6.md 를 참조해 주세요.

Symfony 2.3.x

Symfony 2.3에서 이를 수행하려면 더 이상 보안 컨텍스트에서 토큰만 설정할 수 없습니다.또한 토큰을 세션에 저장해야 합니다.

다음과 같은 방화벽이 있는 보안 파일을 가정합니다.

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

컨트롤러 동작은 다음과 같습니다.

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
    }

}

하려면 , 「」를 합니다.UsernamePasswordToken의 파라미터를 할 수 여기에는 다음 4가지 파라미터를 사용할 수 있습니다.사용자 엔티티, 사용자 자격 증명, 방화벽 이름, 사용자 역할.토큰이 유효하기 위해 사용자 자격 증명을 제공할 필요는 없습니다.

토큰을 설정하는 것이security.context지금 바로 리다이렉트할 경우 필요합니다.데데 、 아플아아아아 아요요 。

그 다음 중요한 부분, 세션 변수 설정.은 '변수 명명규칙'입니다._security_이 예에서는 이름을 붙입니다.main_security_main.

드디어 알아냈어

사용자 등록 후 공급자 구성에서 사용자 엔티티로 설정한 개체 인스턴스에 액세스할 수 있어야 합니다.해결책은 해당 사용자 엔티티를 사용하여 새 토큰을 생성하여 보안 컨텍스트에 전달하는 것입니다.다음은 제 설정에 근거한 예입니다.

RegistrationController.php:

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

서 ★★★★★main는 어플리케이션의 방화벽 이름입니다(@Joe님 감사합니다).이것으로 충분합니다.시스템에서는, 유저가 완전하게 로그인하고 있는 것으로 간주합니다.

편집: @Miquel의 코멘트에 따라 컨트롤러 코드 샘플을 업데이트하여 신규 사용자를 위한 합리적인 기본 역할을 포함시켰습니다(단, 이는 어플리케이션 고유의 요구에 따라 조정할 수 있습니다).

UserInterface 객체가 있는 경우(대부분의 경우), 마지막 인수에 구현되어 있는 getRoles 함수를 사용할 수 있습니다.따라서 함수 logUser를 작성하면 다음과 같이 표시됩니다.

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

저는 Symfony 2.2를 사용하고 있는데, 제 경험은 Problematic과는 조금 달랐기 때문에 이 질문의 모든 정보와 제 자신의 정보를 조합한 것입니다.

나는 조가 의 가치에 대해 틀렸다고 생각한다.$providerKey 「」의 세 .UsernamePasswordToken컨스트럭터사용자가 아닌 인증 프로바이더의 키여야 합니다.인증 시스템에서 서로 다른 공급자를 위해 생성된 토큰을 구별하는 데 사용됩니다.에서 내림차순하는 프로바이더는 프로바이더 키가 자신의 것과 일치하는 토큰만 인증합니다.예를 들어, 는 작성한 토큰의 키를 대응하는 토큰과 일치하도록 설정합니다.이것에 의해, 1개의 파이어 월(fire wall)에 복수의 유저명+패스워드 프로바이더가 존재해, 서로 간섭하지 않게 됩니다.따라서 다른 프로바이더와 경합하지 않는 키를 선택할 필요가 있습니다.사용하고 있다'new_user'.

어플리케이션의 다른 부분에는 인증 성공 이벤트에 따라 달라지는 시스템이 몇 개 있습니다.또, 컨텍스트에 토큰을 설정하는 것만으로 기동되는 것은 아닙니다.난 그걸 얻어야 했어EventDispatcher컨테이너에서 이벤트를 수동으로 발사합니다.명시적인 로그인 요구에 대한 응답이 아니라 암묵적으로 사용자를 인증하기 때문에 대화형 로그인 이벤트도 시작하지 않기로 결정했습니다.

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

「 」를 .$this->get( .. )그럼 스니펫이 컨트롤러 방식으로 되어 있는 것을 전제로 하고 있습니다. 다른 이 '어디서 쓰세요', '어디서 쓰세요', '어디서 쓰세요', '서 쓰세요.ContainerInterface::get( ... )츠키노는 「」를 실장하고 .UserInterface토큰과 함께 바로 사용할 수 있게 되었습니다. 않다면,을 약약면면면면면른, 른른른른른른른른른른른른른른른른른른른른른른른른 if if if if if if if if if로 바꿀 방법을 찾아야 할 입니다.UserInterface인스턴스.

그 코드는 동작하지만, Symfony의 인증 아키텍처를 조작하기보다 해킹하고 있는 것처럼 느껴집니다.새로운 인증 프로바이더를 실장하는 것이, 새로운 인증 프로바이더를 하이잭하는 것보다, 독자적인 토큰 클래스로 실장하는 것이, 보다 정확할 가능성이 있습니다.UsernamePasswordToken또한 적절한 프로바이더를 사용하면 이벤트가 처리됩니다.

Symfony 4.4에서는 컨트롤러 방법으로 다음 작업을 간단히 수행할 수 있습니다(Symfony 설명서 https://symfony.com/doc/current/security/guard_authentication.html#manually-authenticating-a-user) 참조).

// src/Controller/RegistrationController.php
// ...

use App\Security\LoginFormAuthenticator;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;

class RegistrationController extends AbstractController
{
    public function register(LoginFormAuthenticator $authenticator, GuardAuthenticatorHandler $guardHandler, Request $request)
    {
        // ...

        // after validating the user and saving them to the database
        // authenticate the user and use onAuthenticationSuccess on the authenticator
        return $guardHandler->authenticateUserAndHandleSuccess(
            $user,          // the User object you just created
            $request,
            $authenticator, // authenticator whose onAuthenticationSuccess you want to use
            'main'          // the name of your firewall in security.yaml
        );
    }
}

것은 방화벽이 ''으로 되어 있지 입니다.lazy이 경우 토큰은 세션에 저장되지 않으며 로그인하지 않습니다.

firewalls:
    main:
        anonymous: ~ # this and not 'lazy'

내가 여기 온 이유와 똑같은 질문을 가진 사람이 있다면:

부르기

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

에만 을 주다security.context를 참조해 주세요.

즉, 방화벽 제어 내의 URL에서만 사용자를 로그인할 수 있습니다.

합니다.- ( 「 」 「 」 「 」 「 」IS_AUTHENTICATED_ANONYMOUSLY)

여기서 이미 언급한 바와 같이 이 이해하기 어려운 $providerKey 파라미터는 실제로는 아래 예에서는 방화벽 규칙 이름인 'foobar'에 지나지 않습니다.

firewalls:
    foobar:
        pattern:    /foo/

여기서 답을 다 해봤는데 하나도 안 먹혔어.컨트롤러에서 사용자를 인증할 수 있는 유일한 방법은 서브 요구를 한 후 리다이렉트하는 것입니다.silex를 사용하고 있지만 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'));

Symfony 버전 2.8.11(구버전 및 신버전으로 동작하고 있을 가능성이 있음)에서 FOSUserBundle을 사용하는 경우는, 다음의 조작을 실시합니다.

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

다른 솔루션에서 볼 수 있듯이 이벤트를 디스패치할 필요가 없습니다.

인피니트 FOS\UserBundle\Controller\RegistrationController::authenticateUser

(composer.json FOSUserBundle 버전 : "friendsofsymfony/user-bundle" : "~1.3")

언급URL : https://stackoverflow.com/questions/5886713/automatic-post-registration-user-authentication

반응형