簡體   English   中英

FOSUserBundle和HWIOAuthBundle注冊

[英]FOSUserBundle and HWIOAuthBundle registration

我試圖結合FOSUserBundle和HWIOAuthBundle之后的文章,如https://gist.github.com/danvbe/4476697 但是,我不希望自動注冊OAuth2經過身份驗證的新用戶:應由用戶提供其他信息。

期望的結果

我想為注冊用戶提供以下信息:

  • (用戶名,雖然我寧願只使用電子郵件)
  • 顯示名稱(必填)
  • 個人資料圖片(必填)
  • 電子郵件地址(如果沒有Facebook-id則需要)
  • 密碼(如果沒有Facebook-id則需要)
  • Facebook-id(如果沒有電子郵件地址則需要)

現在,當用戶通過Facebook進行身份驗證並且用戶尚不存在時,我希望注冊表單填寫缺失的信息(顯示名稱和個人資料圖片)。 只有在此之后,才應創建新的FOSUser。 在大多數教程中,個人資料圖片和電子郵件地址等字段會自動填充Facebook信息。 這並不總是令人滿意也不可能。

此外,在創建用戶之前,請考慮接受協議條款和您希望顯示的規則。

可能的方法

我認為,解決方案是創建一種新的AnonymousToken,即OAuthenticatedToken,它保存相關的OAuth2信息但不計入身份驗證。 然后,使所有頁面檢查此類身份驗證,並讓其他頁面重定向到OAuth-registration-page。 然而,這對我來說似乎是一個不必要的復雜解決方案。

另一個解決方案可能是從頭開始編寫代碼,而不是使用提到的兩個bundle。 我真的希望這不是必要的。

問:如何在登錄流程的其余部分插入注冊完成代碼?

(我很想分享一些代碼,但由於這是我需要幫助的概念,我沒有太多要展示的。)

編輯:解決方案

繼Derick的adivce之后,我得到了這樣的基礎知識:

自定義用戶提供程序保存信息(遺憾的是,無法訪問原始令牌,因此我無法在注冊后登錄用戶):

class UserProvider extends FOSUBUserProvider {

    protected $session;

    public function __construct(Session $session, UserManagerInterface $userManager, array $properties) {
        $this->session = $session;
        parent::__construct( $userManager, $properties );
    }

    public function loadUserByOAuthUserResponse(UserResponseInterface $response)
    {
        try {
            return parent::loadUserByOAuthUserResponse($response);
        }
        catch ( AccountNotLinkedException $e ) {
            $this->session->set( 'oauth.resource', $response->getResourceOwner()->getName() );
            $this->session->set( 'oauth.id', $response->getResponse()['id'] );
            throw $e;
        }
    }

}

定制失敗處理程序

<?php
// OAuthFailureHandler.php
class OAuthFailureHandler implements AuthenticationFailureHandlerInterface {

    public function onAuthenticationFailure( Request $request, AuthenticationException $exception) {

        if ( !$exception instanceof AccountNotLinkedException ) {
            throw $exception;
        }

        return new RedirectResponse( 'fb-register' );

    }

}

兩者都注冊為服務:

# services.yml
services:
    app.userprovider:
        class: AppBundle\Security\Core\User\UserProvider
        arguments: [ "@session", "@fos_user.user_manager", {facebook: facebookID} ]
    app.oauthfailurehandler:
        class: AppBundle\Security\Handler\OAuthFailureHandler
        arguments: ["@security.http_utils", {}, "@service_container"]

並在安全配置中配置:

# security.yml
security:
    providers:
        fos_userbundle:
            id: fos_user.user_provider.username_email
    firewalls:
        main:
            form_login:
                provider:            fos_userbundle
                csrf_provider:       form.csrf_provider
                login_path:          /login
                check_path:          /login_check
                default_target_path: /profile
            oauth:
                login_path:          /login
                check_path:          /login_check
                resource_owners:
                    facebook:        hwi_facebook_login
                oauth_user_provider:
                    service:         app.userprovider
                failure_handler:     app.oauthfailurehandler
            anonymous:    true
            logout:
                path:           /logout
                target:         /login

在/ fb-register,我讓用戶輸入用戶名並自己保存用戶:

/**
 * @Route("/fb-register", name="hwi_oauth_register")
 */
public function registerOAuthAction(Request $request) {

    $session = $request->getSession();

    $resource = $session->get('oauth.resource');
    if ( $resource !== 'facebook' ) {
        return $this->redirectToRoute('home');
    }

    $userManager = $this->get('fos_user.user_manager');
    $newUser = $userManager->createUser();

    $form = $this->createForm(new RegisterOAuthFormType(), $newUser);
    $form->handleRequest($request);

    if ( $form->isValid() ) {

        $newUser->setFacebookId( $session->get('oauth.id') );
        $newUser->setEnabled(true);

        $userManager->updateUser( $newUser );

        try {
            $this->container->get('hwi_oauth.user_checker')->checkPostAuth($newUser);
        } catch (AccountStatusException $e) {
            // Don't authenticate locked, disabled or expired users
            return;
        }

        $session->remove('oauth.resource');
        $session->remove('oauth.id');
        $session->getFlashBag()
            ->add('success', 'You\'re succesfully registered!' );

        return $this->redirectToRoute('home');
    }

    return $this->render( 'default/register-oauth.html.twig', array(
        'form' => $form->createView()
    ) );

}

用戶之后沒有登錄,這太糟糕了。 此外,正常的fosub功能(編輯配置文件,更改密碼)不再適用於開箱即用。

我只是使用用戶名作為顯示名稱,不知道為什么我之前沒有看到。

第1步:創建自己的用戶提供程序。 擴展OAuthUserProvider並根據您的需求進行自定義。 如果用戶成功進行了操作,則拋出一個特定的異常(可能是accountnotlinkedException)並拋出有關登錄的所有相關數據

第2步:創建自己的身份驗證失敗處理程序。 檢查以確保拋出的錯誤是您在步驟1中提出的錯誤。在此處,您將重定向到填寫其他信息頁面。

這是如何注冊自定義處理程序:

#security.yml
firewall:
    main:
        oauth:
            success_handler: authentication_handler
            failure_handler: social_auth_failure_handler

#user bundle services.yml (or some other project services.yml)
services:
    authentication_handler:
        class: ProjectName\UserBundle\Handler\AuthenticationHandler
        arguments:  ["@security.http_utils", {}, "@service_container"]
        tags:
            - { name: 'monolog.logger', channel: 'security' }

    social_auth_failure_handler:
        class: ProjectName\UserBundle\Handler\SocialAuthFailureHandler
        arguments:  ["@security.http_utils", {}, "@service_container"]
        tags:
            - { name: 'monolog.logger', channel: 'security' }

第3步:在其他信息頁面中創建您的填寫。 拉出您在步驟1中存儲的所有相關數據,並在所有內容都檢出時創建用戶。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM