Мне нужно иметь отдельный URL-адрес для простой формы входа (имя пользователя / пароль), который уже существует в / login, и некоторый URL-адрес, например / login-through-facebook, для входа в систему через процедуру FOSFacebookBundle oauth.
Теперь я не могу понять, как инициировать процедуру oauth-facebook по URL-адресу, он работает, только если я попытаюсь получить доступ к URL-адресу, указанному в «access_control».
Заранее спасибо!
@Matt, большое спасибо за ваше объяснение! Я попытался выполнить ваш ответ, но все еще есть проблема, я не упомянул, что я уже использую 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 в публичных брандмауэрах (но должен ли я вообще это сделать?), он выбрасывает exception You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.
Хитрость состоит в том, чтобы иметь два разделенных входа в вашем брандмауэре, один для входа в форму и один для входа в 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
проверяет наличие facebook oauth2 cookie, если это так, он пытается загрузить вашего пользователя. Если не удается найти файл cookie, процесс аутентификации попробует другой провайдер, если он определен после поставщика facebook.
В вашем случае, когда пользователь пытается перейти на защищенный url (в access_control), отображается страница входа в facebook, и он аутентифицируется, затем он перенаправляется на ваш сайт, cookie найден и пользователь успешно аутентифицирован FOSFacebookBundle
, Чтобы вручную запустить процесс проверки подлинности, поместите кнопку подключения Facebook на свой сайт, а затем в javascript перенаправляет пользователя на другую страницу вашего сайта. Таким образом, cookie будет установлен кнопкой подключения, а FOSFacebookBundle
будет аутентифицировать его по следующему запросу. Что я делаю, это перенаправить пользователя на путь login_check для facebook в javascript, когда кнопка подключения facebook прошла успешно. Таким образом, механизм безопасности перенаправит его, если он указан в конфигурации безопасности.
Надеюсь, это поможет вам достичь того, чего вы хотите. Не будьте осторожны, чтобы задать вопрос, если что-то неясно.
@ Последующий # 1
В самом деле, вы не можете поместить fos_userbundle
под узлом public
в конфигурацию брандмауэра, потому что это fos_userbundle
вариант. Строка fos_userbundle
используется для ссылки на класс FOSUserBundle
UserProvider. Я никогда не использовал этот пакет, но, прочитав документацию, вы должны использовать form_login
. Вы можете посмотреть документацию FOSUserBundle
на шаге 5 и ниже. Ошибка, о которой вы упоминаете, является нечетной, поскольку она говорит вам, что login_path
не обрабатывается брандмауэром, но это так, поскольку брандмауэр соответствует всем, что начинается с /
( ^/
). Не уверен, что происходит не так, но вы идете в правильном направлении. Используйте form_login
и попробуйте проверить, почему он от этого не работает.
С Уважением,
Matt
Вы проверили свой security.yml для:
factories: - "%kernel.root_dir%/../vendor/bundles/FOS/FacebookBundle/Resources/config/security_factories.xml"
Это важно, потому что он будет взимать недостающие опции для службы.
Существует простой пример Bundle, который реализует как FOSUserBundle, так и FOSFacebookBundle, если вы хотите посмотреть https://github.com/ollietb/OhFOSFacebookUserBundle