FOSFacebookBundle不调用自定义提供程序 [英] FOSFacebookBundle does not call custom provider
问题描述
在实现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屋!