如何使用 Symfony2 中的 FOSFacebookBundle 通过 Facebook 制作单独的登录网址 [英] How to make a separate url for signin via Facebook using FOSFacebookBundle in Symfony2

查看:18
本文介绍了如何使用 Symfony2 中的 FOSFacebookBundle 通过 Facebook 制作单独的登录网址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一个单独的 url 用于已存在于/login 上的普通登录表单(用户名/密码),以及一些 url,如/login-via-facebook 以通过 FOSFacebookBundle oauth 程序登录.

I need to have a separate url for plain signin form (username/password) which already exist on /login, and some url like /login-via-facebook to login via FOSFacebookBundle oauth procedure.

现在我不明白如何通过 url 触发 oauth-facebook 程序,它只有在我尝试访问access_control"中列出的 url 时才有效.

Now I can't understand how to trigger oauth-facebook procedure by url, it works only if I try to access url which is listed in "access_control".

提前致谢!

@Matt,非常感谢您的解释!我试着按照你的回答,但还是有问题,我没有提到我已经在使用 FOSUserBundle,

@Matt, thank you very much for your the explanation! I tried to follow your answer, but still have a problem, I didn't mention that I already using FOSUserBundle,

我的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: Unrecognized options "fos_userbundle" under "security.firewalls.public",如果我在公共防火墙中将 fos_userbundle 更改为 form_login(但我应该这样做?),它会引发异常 您必须在安全防火墙配置中使用 form_login 配置要由防火墙处理的检查路径.

so, at this point it throws an exception: InvalidConfigurationException: Unrecognized options "fos_userbundle" under "security.firewalls.public", and if I change fos_userbundle to form_login in public firewalls (but should I do this at all?), it throws an exception You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.

推荐答案

诀窍是在您的防火墙中有两个单独的条目,一个用于表单登录,一个用于 facebook 登录.但就我而言,我有一个登录 URL,用户可以在其中使用他的凭据登录,也可以单击 Facebook 连接以使用 FOSFacebookBundle 通过 Facebook OAuth2 API 进行身份验证.这是我的 security.yml 配置文件示例,用于完成此工作:

The trick is to have two separated entries in your firewall, one for the form login and one for the facebook login. But in my case, I have a single login url where the user can either log in using his credentials or click on a Facebook connect to authenticate via the Facebook OAuth2 API using the FOSFacebookBundle. Here a sample of my security.yml config file to make this work:

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]

这里是我的 routing.yml 文件示例,用于定义完成这项工作所需的安全路由:

And here a sample of my routing.yml file that is used to define security routes required to make this work:

    # 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 登录之前检查使用表单登录的用户.这是因为在 chain_provider 中定义了提供者的顺序.在每个请求中,FOSFacebookBundle 检查是否存在 facebook oauth2 cookie,如果存在,它会尝试加载您的用户.如果找不到 cookie,身份验证过程将尝试另一个提供者,如果它是在 facebook 提供者之后定义的.

Using the security.yml before, the security mechanism will check for user logged in using form prior to user logged in with facebook. This is because the order in which providers are defined in the chain_provider. On each request, the FOSFacebookBundle check if a facebook oauth2 cookie is present, if so, it tries to load your user. If it fails to find the cookie, the authentication process will try another provider, if it is defined after the facebook provider.

在您的情况下,当用户尝试访问受保护的 url(在 access_control 中)时,将显示 facebook 登录页面并进行身份验证,然后将他重定向到您的站点,找到 cookie 并且用户已成功通过身份验证通过 FOSFacebookBundle.要手动触发身份验证过程,请在您的网站上放置一个 facebook 连接按钮,然后在 javascript 中将用户重定向到您网站的另一个页面.这样,cookie 将通过连接按钮设置,FOSFacebookBundle 将在下一个请求中验证他.我所做的是在 facebook 连接按钮成功时将用户重定向到 javascript 中 facebook 的 login_check 路径.这样,安全机制会将他重定向到安全配置中声明的位置.

In your case, when the user tries to go to a protected url (in access_control), the facebook login page is shown and he authenticate, then he is redirected to your site, the cookie is found and the user is authenticated successfully by the FOSFacebookBundle. To manually trigger the authentication process, place a facebook connect button on your site, then, in javascript, redirects the user to another page of your site. This way, the cookie will be set by the connect button and the FOSFacebookBundle will authenticate him on the next request. What I do, is to redirect the user to the login_check path for facebook in javascript when the facebook connect button has been successfull. This way, the security mechanism will redirect him where it is stated in the security configuration.

我希望这能帮助你实现你想要的.如果有什么不清楚的地方,请不要犹豫再问.

I hope this will help you to achieve what you want. Do not hesite to ask further question if something is unclear.

@Follow-up #1

@Follow-up #1

实际上,您不能将 fos_userbundle 放在防火墙配置中的节点 public 下,因为它不是一个有效选项.字符串 fos_userbundle 用于引用 FOSUserBundle UserProvider 类.我从来没有用过这个包,但阅读了文档,你应该使用 form_login.您可以在 FOSUserBundle 的文档>步骤 #5 及以下.您提到的错误很奇怪,因为它告诉您 login_path 不是由防火墙处理的,但情况确实如此,因为防火墙匹配任何以 / (/>^/).不确定出了什么问题,但您正朝着正确的方向前进.使用 form_login 并尝试从那里检查它为什么不起作用.

Indeed, you cannot put fos_userbundle under the node public in the firewall configuration because it is not a valid option. The string fos_userbundle is used to reference FOSUserBundle UserProvider class. I never used this bundle but reading the documentation, you should use form_login. You can look at the documentation of FOSUserBundle in Step #5 and below. The error you mentionning is odd because it tells you that the login_path is not handled by the firewall but it's the case since the firewall matchs anything that start with a / (^/). Not sure what is going wrong but you're going in the right direction. Use form_login and try to check why it's not working from there.

问候,
马特

这篇关于如何使用 Symfony2 中的 FOSFacebookBundle 通过 Facebook 制作单独的登录网址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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