Хитрость заключается в том, чтобы иметь две отдельные записи в брандмауэре, одну для входа в форму и одну для входа в Facebook. Но в моем случае у меня есть один URL-адрес для входа, где пользователь может войти в систему, используя свои учетные данные, или щелкнуть по соединению Facebook, чтобы выполнить аутентификацию через API OAuth2 Facebook, используя FOSFacebookBundle
. Вот пример моего security.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]
А вот пример моего routing.yml
файла, который используется для определения маршрутов безопасности, необходимых для этой работы:
# 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
проверяет наличие файла cookie oauth2 в Facebook, если он пытается загрузить вашего пользователя. Если не удается найти cookie, процесс проверки подлинности будет пытаться использовать другого поставщика, если он определен после поставщика Facebook.
В вашем случае, когда пользователь пытается перейти по защищенному URL-адресу (в access_control), отображается страница входа в Facebook и он аутентифицируется, затем он перенаправляется на ваш сайт, файл cookie обнаруживается, и пользователь успешно проходит аутентификацию. на FOSFacebookBundle
. Чтобы вручную запустить процесс аутентификации, поместите кнопку подключения Facebook на своем сайте, а затем в javascript перенаправьте пользователя на другую страницу вашего сайта. Таким образом, cookie будет установлен с помощью кнопки подключения, и FOSFacebookBundle
подтвердит его подлинность при следующем запросе. Что я делаю, так это перенаправляю пользователя по пути login_check для facebook в javascript, когда кнопка подключения к Facebook была успешной. Таким образом, механизм безопасности перенаправит его туда, где это указано в конфигурации безопасности.
Надеюсь, это поможет вам достичь того, чего вы хотите. Не стесняйтесь задавать дополнительные вопросы, если что-то неясно.
@ Продолжение № 1
Действительно, вы не можете поместить fos_userbundle
под узлом public
в конфигурации брандмауэра, потому что это недопустимая опция. Строка fos_userbundle
используется для ссылки на FOSUserBundle
класс UserProvider. Я никогда не использовал этот пакет, но, читая документацию, вы должны использовать form_login
. Вы можете посмотреть документацию FOSUserBundle
в Step # 5 и ниже. Ошибка, о которой вы упоминаете, является странной, потому что она говорит вам, что login_path
не обрабатывается брандмауэром, но это так, поскольку брандмауэр соответствует всему, что начинается с /
(^/
). Не уверен, что идет не так, но вы идете в правильном направлении. Используйте form_login
и попробуйте проверить, почему он не работает.
С уважением,
Matt