У меня тот же рабочий процесс, что и у вас, и мой пользовательский провайдер пользователей называется правильно, и все работает нормально.
Первое, что вам нужно проверить: есть ли у вас скрипт JavaScript, который перенаправляет пользователя на маршрут login_check
после успешного входа в Facebook через всплывающее окно? Это важно, потому что вызов маршрута 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');
}
}
Надеюсь, что эта помощь, если у вас есть дополнительные вопросы или я что-то неправильно понял из вашей проблемы, не стесняйтесь оставлять комментарии.
С уважением,
Matt