FOSFacebookBundle icon indicating copy to clipboard operation
FOSFacebookBundle copied to clipboard

Using FOSFacebookBundle to bind "fosuserbundle users" to facebook accounts

Open Andy0763 opened this issue 13 years ago • 6 comments

Currently, the custom provider presented in the documentation creates a new user in the FOSUserBundle database, with all its user info extracted from facebook. (basically, the facebookId, email, first and last name)

Would there be an accessible way to use this bundle so that, when a user that has logged in through the form login connects itself for the first time with the facebook button, it updates its database record with new info (in appropriate nullable fields added in the user entity), instead of creating yet another user?

Therefore a user could only login to the website through the form, but this user would then be able to "bind" their website account to their facebook account, if they want to.

Yet I cannot seem to get a firm conviction that this bundle allows to process such a thing without fiddling consistently with its core components...

Andy0763 avatar May 13 '12 17:05 Andy0763

I got this feature working today and it was easier than I thought. I already begun writing some documentation but I'm unsure if this would fit in the current README.md or better be split up in an separate document? Any thoughts @stof or @lsmith77?

daFish avatar May 21 '12 14:05 daFish

I think for now its fine to put it into the README. splitting things up should imho be done in a second step if necessary.

lsmith77 avatar May 21 '12 18:05 lsmith77

Ok, great. This will also fix an issue when a user is already registered and wants to login with his Facebook account having the same email adress.

daFish avatar May 21 '12 19:05 daFish

Thanks for the help!

I also thought of using the email address for identifying already registered users. I think the problem with this solution is that email match is an effective but not sufficient condition: what if the user registered to his facebook account with a different email address than the one he used for the website?

One solution I thought of is trying to store the user's ID in the session before the authentication process hits and the "check_path" disconnects the user, so that I can use the stored ID in the FacebookProvider to identify the user.

An other more "handcrafty" solution would be to design a different facebook button which does not even use authentication on symfony. After facebook oauth, the button would point to a controller which would recover the info stored in the "fbsr_" cookie using the facebook SDK, and modify the user entry in the manager.

What do you think would be the most efficient?

Andy0763 avatar May 23 '12 08:05 Andy0763

I used the email condition to prevent an validation error as email_canonical is defined as unique. But I agree it isn't sufficient.

Another, third, solution would be: Still have the normal and Facebook login page but add a new button to the users profile edit page to connect the account. This could be handled independently from the registration process.

daFish avatar May 23 '12 09:05 daFish

Hello!

I'm crazy with this bundle. I have did all the indications of Readme. But I don't know how I can associate my users of my site web, with FOSFacebookBundle. The entity of FOSUserBundle has fields facebook_uid and following the documentation of FOSFacebookBundle I created a field facebookId. But my question is: How can user associate his count of my web with his count of facebook?

I use symfony2.1.3-dev. My config.yml is:

fos_facebook:
    file: %kernel.root_dir%/../vendor/facebook/php-sdk/src/base_facebook.php
    alias: facebook
    app_id: myid
    secret: mysecret
    cookie: tre
    permissions: [email, user_birthday, user_location]
services:
    my.facebook.user:
        class: project\myBundle\Security\User\Provider\FacebookProvider
        arguments:
            facebook: "@fos_facebook.api"
            userManager: "@fos_user.user_manager"

routing.yml

#FosFacebookBundle
_security_check:
      pattern:  /login_check_fb
_security_logout:
      pattern:  /logout

security.yml

providers:
        fos_userbundle:
            id: fos_user.user_provider.username
        my_fos_facebook_provider:
              id: my.facebook.user
    firewalls:
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false
        admin:
            switch_user: true
            context: user
            pattern: /admin(.*)
            form_login:
                provider: fos_userbundle
                login_path: /admin/login
                use_forward: false
                check_path: /admin/login_check
                failure_path: null
                use_referer: true #redirige al usuario a la pagina que venia antes de hacer login
            logout:
                path: /admin/logout
                target: / #url a la que va a ir despues de logout

            anonymous: true
       main:
            pattern: ^/*
            form_login:
                provider: fos_userbundle
                csrf_provider: form.csrf_provider
            fos_facebook:
                app_url: "http://apps.facebook.com/subireventos/"
                server_url: "http://localhost/workspace/web/app_dev.php/"
                login_path: /login
                check_path: /login_check_fb
                provider: my_fos_facebook_provider
            logout:
                handlers: ["fos_facebook.logout_handler"]
            anonymous:    true

In my base.html.twig I included:

{{ facebook_initialize({'xfbml': true, 'fbAsyncInit': 'onFbInit();'}) }}

And in one of the page of login(FOSUserBundle) included: ( with this line code, the user can log on facebook, from my web)

{{ facebook_login_button({'autologoutlink': true}) }}
<script>
  function goLogIn(){
      window.location.href = "{{ path('_security_check') }}";
  }

  function onFbInit() {
      if (typeof(FB) != 'undefined' && FB != null ) {
          FB.Event.subscribe('auth.statusChange', function(response) {
              if (response.session || response.authResponse) {
                  setTimeout(goLogIn, 500);
              } else {
                  window.location.href = "{{ path('_security_logout') }}";
              }
          });
      }
  }
</script>

But I don't know how complete the field facebookId and asociate an user facebook - my web I tried several changes, but nothing works. I can log in my web or from facebook, but is separate. Have I what to do anything in app facebook? PLEASE HELP! : )

Chrysweel avatar Oct 10 '12 18:10 Chrysweel