Php 如何使用Symfony2中的FOSFacebookBundle通过Facebook为signin创建单独的url

Php 如何使用Symfony2中的FOSFacebookBundle通过Facebook为signin创建单独的url,php,symfony,Php,Symfony,我需要为/login上已经存在的普通登录表单(用户名/密码)提供一个单独的url,以及一些类似/login via facebook的url,以便通过FOSFacebookBundle oauth过程登录 现在我不明白如何通过url触发oauth facebook过程,只有当我尝试访问“访问控制”中列出的url时,它才会起作用 提前谢谢 @马特,非常感谢你的解释! 我试着遵循你的答案,但仍然有一个问题,我没有提到我已经在使用FOSUserBundle mysecurity.yml: provi

我需要为/login上已经存在的普通登录表单(用户名/密码)提供一个单独的url,以及一些类似/login via facebook的url,以便通过FOSFacebookBundle oauth过程登录

现在我不明白如何通过url触发oauth facebook过程,只有当我尝试访问“访问控制”中列出的url时,它才会起作用

提前谢谢


@马特,非常感谢你的解释! 我试着遵循你的答案,但仍然有一个问题,我没有提到我已经在使用FOSUserBundle

my
security.yml

providers:
    chain_provider:
      providers: [fos_userbundle, fos_facebook]
    fos_userbundle:
        id: fos_user.user_manager
    fos_facebook:
        id: fos_facebook.auth 

firewalls:      
    public:
      pattern:   ^/
      fos_facebook:
        app_url: ""
        server_url: ""
        login_path: /login
        check_path: /login_check/facebook
        provider: fos_userbundle
      fos_userbundle:
        login_path: /login
        check_path: /login_check/form
        provider: fos_userbundle
      anonymous: true
      logout:    true`

因此,此时它抛出了一个异常:
InvalidConfigurationException:security.firewalls.public“
下无法识别的选项“fos\u userbundle”,如果我将fos\u userbundle更改为在公共防火墙中形成\u登录(但我应该这样做吗?),它抛出一个异常
您必须在安全防火墙配置中使用form\u登录配置防火墙要处理的检查路径。

诀窍是在防火墙中有两个单独的条目,一个用于form登录,另一个用于facebook登录。但在我的例子中,我有一个单一的登录url,用户可以使用他的凭据登录,或者单击Facebook连接,使用
FOSFacebookBundle
通过Facebook OAuth2 API进行身份验证。下面是我的
security.yml
config文件的一个示例,以实现此功能:

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

  providers:
    chain_provider:
      providers: [acme.form_provider, acme.facebook_provider]
    acme.form_provider:
      id: acme.user_provider.form
    acme.facebook_provider:
      id: acme.user_provider.facebook

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

    public:
      pattern:   ^/
      fos_facebook:
        app_url: "your_app_url"
        server_url: "your_server_url"
        login_path: /login
        check_path: /login_check/facebook
        provider: acme.facebook_provider
      form_login:
        login_path: /login
        check_path: /login_check/form
        provider: acme.form_provider
      anonymous: true
      logout:    true

  role_hierarchy:
    ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
    # This is defined to let the user log in. The controller for
    # route display the login form and a facebook connect button
_security_login:
    pattern:   /login
    defaults:  { _controller: AcmeAcmeBundle:Main:login }

# This is defined for the form login authentication, 
# no controller is associated with it
_security_check_form:
    pattern:   /login_check/form

# This is defined for facebook login authentication, 
# a controller is associated with it but does nothing
_security_check_facebook:
    pattern:   /login_check/facebook
            defaults:  { _controller: AcmeAcmeBundle:Main:loginCheckFacebook }

_security_logout:
    pattern:   /logout
    defaults:  { _controller: AcmeAcmeBundle:Main:logout }
这里是我的
routing.yml
文件的一个示例,用于定义实现此功能所需的安全路由:

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

  providers:
    chain_provider:
      providers: [acme.form_provider, acme.facebook_provider]
    acme.form_provider:
      id: acme.user_provider.form
    acme.facebook_provider:
      id: acme.user_provider.facebook

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

    public:
      pattern:   ^/
      fos_facebook:
        app_url: "your_app_url"
        server_url: "your_server_url"
        login_path: /login
        check_path: /login_check/facebook
        provider: acme.facebook_provider
      form_login:
        login_path: /login
        check_path: /login_check/form
        provider: acme.form_provider
      anonymous: true
      logout:    true

  role_hierarchy:
    ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
    # This is defined to let the user log in. The controller for
    # route display the login form and a facebook connect button
_security_login:
    pattern:   /login
    defaults:  { _controller: AcmeAcmeBundle:Main:login }

# This is defined for the form login authentication, 
# no controller is associated with it
_security_check_form:
    pattern:   /login_check/form

# This is defined for facebook login authentication, 
# a controller is associated with it but does nothing
_security_check_facebook:
    pattern:   /login_check/facebook
            defaults:  { _controller: AcmeAcmeBundle:Main:loginCheckFacebook }

_security_logout:
    pattern:   /logout
    defaults:  { _controller: AcmeAcmeBundle:Main:logout }
使用之前的
security.yml
,安全机制将在用户登录facebook之前检查用户是否使用表单登录。这是因为在
链\u provider
中定义提供程序的顺序不同。在每个请求中,
FOSFacebookBundle
检查是否存在facebook oauth2 cookie,如果存在,它将尝试加载您的用户。如果找不到cookie,验证过程将尝试另一个提供者,如果它是在facebook提供者之后定义的

在您的情况下,当用户尝试转到受保护的url(在access\u控件中)时,将显示facebook登录页面,并进行身份验证,然后将其重定向到您的站点,找到cookie,并且用户通过
FOSFacebookBundle
成功进行身份验证。要手动触发身份验证过程,请在站点上放置一个facebook connect按钮,然后在javascript中将用户重定向到站点的另一个页面。这样,cookie将通过connect按钮进行设置,
FOSFacebookBundle
将在下一个请求中对其进行身份验证。我要做的是,当facebook connect按钮成功时,将用户重定向到javascript中facebook的登录检查路径。这样,安全机制会将他重定向到安全配置中指定的位置

我希望这将帮助你实现你想要的。如果有什么不清楚的地方,不要犹豫问进一步的问题

@后续行动#1

实际上,您不能将
fos_userbundle
放在防火墙配置中的节点
public
下,因为它不是有效选项。字符串
fos\u userbundle
用于引用
FOSUserBundle
UserProvider类。我从未使用过这个捆绑包,但在阅读文档时,您应该使用
form\u login
。您可以查看中及下面的
FOSUserBundle
文档。您提到的错误很奇怪,因为它告诉您,
登录路径
不是由防火墙处理的,但它是这样的,因为防火墙匹配以
/
开头的任何内容(
^/
)。不确定哪里出了问题,但你正朝着正确的方向前进。使用
form\u login
并尝试从那里检查它为什么不起作用

问候,

Matt

您是否检查了您的security.yml:

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

这一点很重要,因为它将对服务缺少的选项收费。

如果您想查看,有一个简单的示例捆绑包,它同时实现了FOSUserBundle和FOSFacebookBundle

非常感谢,我已经编辑了这个问题,请看您是否有时间。我在我的回答中添加了后续内容。这实际上解决了我的一个错误。感谢您在此线程中的输入感谢您发布此消息!我使用您的代码创建了完整的Symfony 2.1应用程序: