2012-01-28 17 views
6

Próbuję skonfigurować FOSFacebookBundle i FOSUserBundle, aby użytkownicy mogli logować się przy użyciu zarejestrowanych kont lub kont na Facebooku.FOSFacebookBundle i FOSUserBundle

Tutaj odpowiednie kody:

config.yml:

fos_user: 
db_driver: orm 
firewall_name: public 
user_class: Fam\DiaBundle\Entity\User 
from_email: 
    address:  [email protected] 
    sender_name: Staff 
registration: 
    confirmation: 
     enabled: true 

fos_facebook: 

    file: %kernel.root_dir%/../vendor/facebook/src/base_facebook.php 
    alias: facebook 
    app_id: 1234567890 
    secret: abcdefg1234567890 
    cookie: true 
    permissions: [email] 
    culture: us_US 

security.yml

# 
# app/config/security.yml 
# 
# 

services: 
    my.facebook.user: 
     class: Fam\Dia\Security\User\Provider\FacebookProvider 
     arguments: 
      facebook: "@fos_facebook.api" 
      userManager: "@fos_user.user_manager" 
      validator: "@validator" 
      container: "@service_container" 
security: 
    factories: 
     - "%kernel.root_dir%/../vendor/bundles/FOS/FacebookBundle/Resources/config/security_factories.xml" 

    providers: 
     chain_provider: 
      providers: [fos_userbundle, my_fos_facebook_provider] 
     fos_userbundle: 
      id: fos_user.user_manager 
     my_fos_facebook_provider: 
      id: my.facebook.user 

encoders: 
     "FOS\UserBundle\Model\UserInterface": sha512 

    firewalls: 
     public: 
      pattern: ^/ 
      fos_facebook: 
      app_url: "http://apps.facebook.com/dia/" 
      server_url: "http://diafam.com/facebookApp/" 
      login_path: /login 
      check_path: /login_check 
      default_target_path:/
      provider: my_fos_facebook_provider 
      form_login: 
      login_path: /login 
      check_path: /login_check 
      provider: fos_userbundle 
      anonymous: true 
      logout: true    


    access_control: 
     - { path: ^/secured/.*, role: [IS_AUTHENTICATED_FULLY] } # This is the route secured with  fos_facebook 
     - { path: ^/facebook/, role: [ROLE_FACEBOOK] } 
     - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY } 
     - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY } 
     - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY } 
     - { path: ^/admin/, role: ROLE_ADMIN } 
     # FOS facebook 
     - { path: ^/login_check, role: IS_AUTHENTICATED_ANONYMOUSLY } 
     - { path: ^/.*, role: [IS_AUTHENTICATED_ANONYMOUSLY] } 
     #- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https } 

routing.yml

_security_check: 
     pattern: /login_check 
_security_logout: 
     pattern: /logout 

_security_login: 
     pattern: /login 

FacebookProvider.php

<?php 

// src/Fam\DiaBundle\Security\User\Provider/FacebookProvider.php 

namespace Fam\DiaBundle\Security\User\Provider; 

use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; 
use Symfony\Component\Security\Core\Exception\UnsupportedUserException; 
use Symfony\Component\Security\Core\User\UserProviderInterface; 
use Symfony\Component\Security\Core\User\UserInterface; 
use \BaseFacebook; 
use \FacebookApiException; 

class FacebookProvider implements UserProviderInterface 
{ 
    /** 
    * @var \Facebook 
    */ 
    protected $facebook; 
protected $userManager; 
protected $validator; 

public function __construct(BaseFacebook $facebook, $userManager, $validator) 
{ 
    $this->facebook = $facebook; 
    $this->userManager = $userManager; 
    $this->validator = $validator; 
} 

public function supportsClass($class) 
{ 
    return $this->userManager->supportsClass($class); 
} 

public function findUserByFbId($fbId) 
{ 
    return $this->userManager->findUserBy(array('facebookId' => $fbId)); 
} 

public function loadUserByUsername($username) 
{ 
    $user = $this->findUserByFbId($username); 

    try { 
     $fbdata = $this->facebook->api('/me'); 
    } catch (FacebookApiException $e) { 
     $fbdata = null; 
    } 

    if (!empty($fbdata)) { 
     if (empty($user)) { 
      $user = $this->userManager->createUser(); 
      $user->setEnabled(true); 
      $user->setPassword(''); 
     } 

     // TODO use http://developers.facebook.com/docs/api/realtime 
     $user->setFBData($fbdata); 

     if (count($this->validator->validate($user, 'Facebook'))) { 
      // TODO: the user was found obviously, but doesnt match our expectations, do something smart 
      throw new UsernameNotFoundException('The facebook user could not be stored'); 
     } 
     $this->userManager->updateUser($user); 
    } 

    if (empty($user)) { 
     throw new UsernameNotFoundException('The user is not authenticated on facebook'); 
    } 

    return $user; 
} 

public function refreshUser(UserInterface $user) 
{ 
    if (!$this->supportsClass(get_class($user)) || !$user->getFacebookId()) { 
     throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user))); 
    } 

    return $this->loadUserByUsername($user->getFacebookId()); 
    } 
} 

login.html.twig

{% extends '::base.html.twig' %} 


{% block body %} 
{{ facebook_initialize({'xfbml': true, 'fbAsyncInit': 'onFbInit();'}) }} 
{{ 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> 


    {% for key, message in app.session.getFlashes() %} 
    <div class="{{ key }}"> 
     {{ message|trans({}, 'FOSUserBundle') }} 
    </div> 
    {% endfor %} 


{% if error %} 
    <div>{{ error }}</div> 
{% endif %} 

<form action="{{ path("fos_user_security_check") }}" method="post"> 
    <h5><label for="username">{{ 'security.login.username'|trans({}, 'FOSUserBundle') }}</label><br/> 
    <input type="text" id="username" name="_username" value="{{ last_username }}" size=30 /><p> 

    <label for="password">{{ 'security.login.password'|trans({}, 'FOSUserBundle') }}</label><br/> 
    <input type="password" id="password" name="_password" size=30 /><p> 

    <input type="checkbox" id="remember_me" name="_remember_me" value="on" /> 
    <label for="remember_me">{{ 'security.login.remember_me'|trans({}, 'FOSUserBundle') }}</label><p> 

    <input type="submit" id="_submit" name="_submit" value="Entra" /> 
</form> 
     </div> 

{% endblock body %} 

Może mi pan pomóc?

+1

Na czym polega problem?!? – Matt

+0

Kiedy próbuję zalogować się przy pomocy FOSUser, otrzymuję komunikat: "Nie można pobrać użytkownika Facebooka z sesji.". Zaloguj się na Facebooku i idź w prawo. – Vittore

Odpowiedz

5

Oto rozwiązanie:

w routing.yml

_security_check: 
    pattern: /loginFb 

w security.yml:

 fos_facebook: 
     check_path: /loginFb 

w domyślnym kontrolerem:

/** 
* Dummy controller. 
* 
* @Route("/loginFb") 
* @Template 
* 
* 
* */ 
public function loginFbAction() { 
} 
+0

Witam, mam do czynienia z dokładnie ten sam problem, próbowałem powyżej rozwiązania nadal jestem przekierowany do kontrolera login_check po zalogowaniu. i otrzymuję błąd. http://stackoverflow.com/questions/21326458/fosfacebookbundle-error-after-login-the-controller-must-return--response-null – vishal

Powiązane problemy