FOSFacebookBundle不调用自定义提供程序 [英] FOSFacebookBundle does not call custom provider

查看:89
本文介绍了FOSFacebookBundle不调用自定义提供程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在实现FOSFacebookBundle时,我面临着一个大问题.

I'm facing big issue while implementing FOSFacebookBundle.

我关注了文档,并遇到以下情况: *当用户单击登录"时,将显示一个弹出窗口 *在用户授予该应用程序权限后,"FB"按钮将被更改(以注销")

I followed the docs and have following situation: * when user clicks login a popup appears * after user grants permission to the app, FB button is being changed (to Logout)

但是,没有调用我的自定义提供程序(仅调用了一个构造函数)-是的,我使用了一个笨拙的调试方法(使用类方法的名称创建空文件:-)).

However, my custom provider is not called (only a constructor is called) - yes, I use a noobish debug method (creating empty files with the name of the class method :-)).

有人有何建议吗?有提示吗?

Anybody has any suggestion why? Any tips?

修改
经过一段时间尝试解决该问题后,我感到迷路了.

Edit
After some time of trying to solve that issue, I feel I'm lost.

再次,这是我的配置:

app/config/config.yml:

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:

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 }

app/config/security.yml

app/config/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

我还在将代码实现到树枝模板中,如docs所示(也实现了来自@Matt的代码段).

I'm also implementing code into twig template as shown in docs (also implemented snippet from @Matt).

推荐答案

我的工作流程与您相同,并且正确调用了我的自定义用户提供程序,并且一切正常.

I have the same workflow as you and my custom user provider is called correctly and everything is working fine.

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

The first thing that you need to check is: do you have a JavaScript script that redirects the user to the login_check route after it has successfully login into Facebook via the popup? This is important because calling the login_check route after a valid authentication will trigger the security mechanism of Symfony2 that will call the FOSFacebookBundle special security code that will then call your own custom user provider. I think you may be just missing this small piece.

以下是使其工作(使用jQuery)所需的JavaScript代码:

Here the pieces of JavaScript code required to make it work (using 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放在这里只是为了帮助您检查与您自己的文件之间的差异:

I put here my security.yml just to help you check for differences with your own file:

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

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

And my service definition for the custom user provider we use:

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的控制器中执行动作的示例:

You also need to create a new route for the /login_check, /login and /logout paths. Those route will be hooked by Symfony2 for the security process. Here an example of the implementation of the actions in a controller called MainController in my cases:

<?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');
    }
}

希望获得帮助,如果您还有其他问题,或者我对您的问题有所误解,请随时发表评论.

Hope this help, if you have more questions or I misunderstand something from your problem, don't hesitate to leave a comment.

关于,
马特

这篇关于FOSFacebookBundle不调用自定义提供程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆