FOSFacebookBundle and FOSUserBundle

≯℡__Kan透↙ 提交于 2020-01-01 03:31:09

问题


I'm trying to setup FOSFacebookBundle and FOSUserBundle, so users can login with registered accounts or facebook accounts.

Here relevant codes:

config.yml:

fos_user:
db_driver: orm 
firewall_name: public
user_class: Fam\DiaBundle\Entity\User
from_email:
    address:        info@famdia.com
    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 %}

May you help me?


回答1:


Here the solution:

in routing.yml

_security_check:
     pattern:  /loginFb

in security.yml:

      fos_facebook:
        check_path: /loginFb

in default controller:

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



回答2:


https://github.com/FriendsOfSymfony/FOSFacebookBundle/tree/2.0#include-the-login-button-in-your-templates says:

Note that we wait 500ms before redirecting to let the browser dealing with the Facebook cookie. You can avoid this step but you might get this error message: "The Facebook user could not be retrieved from the session."



来源:https://stackoverflow.com/questions/9046669/fosfacebookbundle-and-fosuserbundle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!