FOSFacebookBundle不会调用自定义提供程序

时间:2011-08-31 12:55:35

标签: facebook symfony

我在实施FOSFacebookBundle时面临重大问题。

我按照文档进行了以下情况: *当用户点击登录时,会出现一个弹出窗口 *用户授予应用程序权限后,FB按钮正在更改(退出)

但是,我的自定义提供程序未被调用(仅调用构造函数) - 是的,我使用noobish调试方法(使用类方法的名称创建空文件: - ))。

有人有什么建议吗?有什么提示吗?

修改
经过一段时间试图解决这个问题后,我觉得自己迷失了。

再一次,这是我的配置:

app / config / config.yml:

fos_facebook:
    file:   %kernel.root_dir%/../vendor/facebook/src/base_facebook.php
    alias:  facebook
    app_id: xxx
    secret: xxx
    cookie: true
    permissions: [email, user_location]

app / config / routing.yml:

_security_login:
    pattern: /login
    defaults: { _controller: TestBundle:Main:login }

_security_check:
    pattern:  /login_check
    defaults: { _controller: TestBundle:Main:loginCheck }

_security_logout:
    pattern:  /logout
    defaults: { _controller: TestBundle:Main:logout }

应用程序/配置/ security.yml

security:
    factories:
        -"%kernel.root_dir%/../vendor/bundles/FOS/FacebookBundle/Resources/config/security_factories.xml"
    providers:
        my_fos_facebook_provider:
            id: my.facebook.user
        fos_userbundle:
            id: fos_user.user_manager
firewalls:
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false

        main:
            pattern: ^/
            form_login:
                provider: fos_userbundle
                login_path: /login
                check_path: /login_check
            logout:       true
            anonymous:    true

        public:
            pattern:   ^/.*
            fos_facebook:
                app_url: "http://www.facebook.com/apps/application.php?id=xxx"
                server_url: "http://symfonytest.com.dev/app_dev.php/"
                login_path: /login
                check_path: /login_check
                provider: my_fos_facebook_provider
                default_target_path: /
            anonymous: true
            logout: true

我还将代码实现到twig模板中,如docs所示(也是@Matt实现的片段)。

1 个答案:

答案 0 :(得分:6)

我有与您相同的工作流程,我的自定义用户提供程序被正确调用,一切正常。

您需要检查的第一件事是:您是否有一个JavaScript脚本在用户通过弹出窗口成功登录Facebook后将用户重定向到login_check路由?这很重要,因为在有效身份验证后调用login_check路由将触发Symfony2的安全机制,该机制将调用FOSFacebookBundle特殊安全代码,然后调用您自己的自定义用户提供程序。我想你可能只是错过了这一小块。

这里需要的JavaScript代码片段(使用jQuery):

$(document).ready(function() {
    Core.facebookInitialize();
}); 

var Core = { 
    /**
     * Initialize facebook related things. This function will subscribe to the auth.login
     * facebook event. When the event is raised, the function will redirect the user to
     * the login check path.
     */
    facebookInitialize = function() {
        FB.Event.subscribe('auth.login', function(response) {
            Core.performLoginCheck();
        });
    };

    /**
     * Redirect user to the login check path.
     */
    performLoginCheck = function() {
        window.location = "http://localhost/app_dev.php/login_check";
    }
}

我把security.yml放在这里只是为了帮助您检查与自己文件的差异:

security:
    factories:
    - "%kernel.root_dir%/../vendor/bundles/FOS/FacebookBundle/Resources/config/security_factories.xml"

  providers:
    acme.facebook_provider:
      # This is our custom user provider service id. It is defined in config.yml under services
      id: acme.user_provider

  firewalls:
    dev:
      pattern:  ^/(_(profiler|wdt)|css|images|js)/
      security: false

    public:
      pattern:   ^/
      fos_facebook:
        app_url: "http://www.facebook.com/apps/application.php?id=FACEBOOK_APP_ID"
        server_url: "http://localhost/app_dev.php/"
        default_target_path: /
        login_path: /login
        check_path: /login_check
        provider: acme.facebook_provider
      anonymous: true
      logout:    true

我们使用的自定义用户提供程序的服务定义:

services:
  acme.user_provider:
    class: Application\AcmeBundle\Security\User\Provider\UserProvider
    arguments:
      facebook:      "@fos_facebook.api"
      entityManager: "@doctrine.orm.entity_manager"
      validator:     "@validator"

您还需要为/login_check/login/logout路径创建新路线。这些路由将被Symfony2挂钩以进行安全处理。这是一个在我的案例中名为MainController的控制器中执行操作的示例:

<?php

namespace Application\AcmeBundle\Controller;

use ...;

class MainController extends Controller
{
    /**
     * This action is responsible of displaying the necessary informations for
     * a user to perform login. In our case, this will be a button to connect
     * to the facebook API.
     *
     * Important notice: This will be called ONLY when there is a problem with
     * the login_check or by providing the link directly to the user.
     *
     * @Route("/{_locale}/login", name = "_security_login", defaults = {"_locale" = "en"})
     */
    public function loginAction()
    {
        if ($this->request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
            $error = $this->request->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
        } else {
            $error = $this->request->getSession()->get(SecurityContext::AUTHENTICATION_ERROR);
        }
        return $this->render('AcmeBundle:Main:login.html.twig', array(
            'error' => $error
        ));
    }

    /**
     * This action is responsible of checking if the credentials of the user
     * are valid. This will not be called because this will be intercepted by the
     * security component of Symfony.
     *
     * @Route("/{_locale}/login_check", name = "_security_check", defaults = {"_locale" = "en"})
     */
    public function loginCheckAction()
    {
        // Call intercepted by the Security Component of Symfony
    }

    /**
     * This action is responsible of login out a user from the site. This will
     * not be called because this will be intercepted by the security component
     * of Symfony.
     *
     * @Route("/{_locale}/logout", name = "_security_logout", defaults = {"_locale" = "en"})
     */
    public function logoutAction()
    {
        return $this->redirect('index');
    }
}

希望这有帮助,如果您有更多问题或我误解了您的问题,请不要犹豫,发表评论。

的问候,
马特