質問

I've been following the instruction here: https://gist.github.com/danvbe/4476697, I have read the entire thread more than once, but I'm not getting a solution for my problem. I want to use the oauth bundle just for account linking, persisting the user data from oauth provider. My users will not be authenticated using oauth. Nevertheless, I have implemented the whole thing to see if it works with github as provider, but nothing. I'm able to go to the authorization page, but when I click on Allow Access, I'm inevitable redirected to the login page with this error No oauth code in the request. If stop using the custom FOSUBUserProvider and change to the default HWI one, then I get the app registered in Github but cannot persist the data.

Important: I tried replicating exactly the FOSUBUserProvider from HWI and the same problem remained, so probably is not related it's implementation but maybe with the service definition or the config. Any help is greatly appreciated.

These are the relevant files:

FOSUBUserProvider.php

class FOSUBUserProvider extends BaseClass
{
    /**
     * {@inheritDoc}
     */
    public function connect(UserInterface $user, UserResponseInterface $response)
    {
        $property = $this->getProperty($response);
        $username = $response->getUsername();

        //on connect - get the access token and the user ID
        $service = $response->getResourceOwner()->getName();

        $setter = 'set'.ucfirst($service);
        $setter_id = $setter.'Id';
        $setter_token = $setter.'AccessToken';

        //we "disconnect" previously connected users
        if (null !== $previousUser = $this->userManager->findUserBy(array($property => $username))) {
            $previousUser->$setter_id(null);
            $previousUser->$setter_token(null);
            $this->userManager->updateUser($previousUser);
        }

        //we connect current user
        $user->$setter_id($username);
        $user->$setter_token($response->getAccessToken());

        $this->userManager->updateUser($user);
    }

    /**
     * {@inheritdoc}
     */
    public function loadUserByOAuthUserResponse(UserResponseInterface $response)
    {
        $username = $response->getUsername();
        $user = $this->userManager->findUserBy(array($this->getProperty($response) => $username));
        //when the user is registrating
        if (null === $user) {
            $service = $response->getResourceOwner()->getName();
            $setter = 'set'.ucfirst($service);
            $setter_id = $setter.'Id';
            $setter_token = $setter.'AccessToken';
            // create new user here
            $user = $this->userManager->createUser();
            $user->$setter_id($username);
            $user->$setter_token($response->getAccessToken());
            //I have set all requested data with the user's username
            //modify here with relevant data
            $user->setUsername($username);
            $user->setEmail($username);
            $user->setPassword($username);
            $user->setEnabled(true);
            $this->userManager->updateUser($user);
            return $user;
        }

        //if user exists - go with the HWIOAuth way
        $user = parent::loadUserByOAuthUserResponse($response);

        $serviceName = $response->getResourceOwner()->getName();
        $setter = 'set' . ucfirst($serviceName) . 'AccessToken';

        //update access token
        $user->$setter($response->getAccessToken());

        return $user;
    }

}

config.yml

hwi_oauth:
    #this is my custom user provider, created from FOSUBUserProvider - will manage the
    #automatic user registration on your site, with data from the provider (facebook. google, etc.)
    #and also, the connecting part (get the token and the user_id)
    connect:
        account_connector: custom.user.provider
    # name of the firewall in which this bundle is active, this setting MUST be set
    firewall_name: main

    # optional FOSUserBundle integration
    fosub:
        # try 30 times to check if a username is available (foo, foo1, foo2 etc)
        username_iterations: 30

        # mapping between resource owners (see below) and properties
        properties:
            github: githubId

    # optional HTTP Client configuration
    http_client:
        verify_peer:   false

    resource_owners:
        github:
            type:                 github
            client_id:            xxxxxxxxxxxxxxxxxxxxxx
            client_secret:        xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
            scope:                "repo, delete_repo, notifications, gist"
            options:
                csrf:             true

security.yml

providers:
        fos_userbundle:
            id: fos_user.user_provider.username_email

    firewalls: #CAUTION! The order of the firewalls IS ON PURPOSE! DON'T CHANGE!
        # Disabling the security for the web debug toolbar, the profiler and Assetic.
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false

        # -> custom firewall for the admin area of the URL
        admin:
            pattern:            /admin(.*)
            context:            user
            form_login:
                provider:       fos_userbundle
                login_path:     /admin/login
                use_forward:    false
                check_path:     /admin/login_check
                failure_path:   null
            logout:
                path:           /admin/logout
            anonymous:          true

        # -> end custom configuration

        # defaut login area for standard users

        # This firewall is used to handle the public login area
        # This part is handled by the FOS User Bundle
        main:
            pattern:             .*
            context:             user
            form_login:
                provider:       fos_userbundle
                login_path:     /login
                use_forward:    false
                check_path:     /login_check
                failure_path:   null
            logout:             true
            anonymous:          true

            # Login path for OAuth providers
            oauth:
                resource_owners:
                    github:             "/login/check-github"
                    trello:             "/login/check-trello"
                login_path:        /login
                failure_path:      /login

                # FOSUB integration
#                oauth_user_provider:
#                    service: hwi_oauth.user.provider.fosub_bridge
                oauth_user_provider:
                    #this is my custom user provider, created from FOSUBUserProvider - will manage the
                    #automatic user registration on website, with data from the provider (github. trello, etc.)
                    service: custom.user.provider

    access_control:
        # URL of FOSUserBundle which need to be available to anonymous users
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }

        # Admin login page needs to be access without credential
        - { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/login_check$, role: IS_AUTHENTICATED_ANONYMOUSLY }

        # Secured part of the site
        # This config requires being logged for the whole site and having the admin role for the admin part.
        # Change these rules to adapt them to your needs
        - { path: ^/admin/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }
        - { path: ^/.*, role: ROLE_USER } #This is on purpose.

routing.yml

hwi_oauth_security:
    resource: "@HWIOAuthBundle/Resources/config/routing/login.xml"
    prefix: /connect

hwi_oauth_connect:
    resource: "@HWIOAuthBundle/Resources/config/routing/connect.xml"
    prefix: /connect

hwi_oauth_redirect:
    resource: "@HWIOAuthBundle/Resources/config/routing/redirect.xml"
    prefix:   /connect

services.yml

parameters:
    custom.user.provider.class: My\Bundle\Path\Security\Core\User\FOSUBUserProvider

services:
    sonata.admin.user:
        class: My\Bundle\Path\Admin\Model\UserAdmin
        tags:
#            - { name: sonata.admin, manager_type: orm, group: users, label: users, label_translator_strategy: sonata.admin.label.strategy.underscore }
        arguments:
            - ~
            - My\Bundle\Path\Entity\User
            - SonataAdminBundle:CRUD
        calls:
            - [setTranslationDomain, [SonataUserBundle]]
            - [setUserManager, [@fos_user.user_manager]]
            - [setSecurityContext, [@security.context]]

    custom.user.provider:
        class: "%custom.user.provider.class%"
        #this is the place where the properties are passed to the UserProvider - see config.yml
        arguments: [@fos_user.user_manager,{github: github_id, trello: trello_id}]
役に立ちましたか?

解決

Well, after a lot of try and error, I found the problem:

The callback URL in Github was: http://mywebsite/login/check-github but that was wrong. The truth is that I never found what this value had to be set up to, so I was guessing. By accident I discovered the right URL: http://mywebsite/connect/service/github applicable in my case, with my configuration.

I found it in one of the times in wich I tried the default HWI Provider, inspecting the redirects with the browser console.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top