Как сделать отдельный URL для входа через Facebook с помощью FOSFacebookBundle в Symfony2 - PullRequest
5 голосов
/ 17 ноября 2011

Мне нужен отдельный URL-адрес для простой формы входа (имя пользователя / пароль), которая уже существует на / login, и некоторые URL-адреса, такие как / login-via-facebook, для входа через процедуру oauth FOSFacebookBundle.

Теперь я не могу понять, как вызвать процедуру oauth-facebook по URL, она работает, только если я пытаюсь получить доступ к URL, указанному в "access_control".

Заранее спасибо!


@ Мэтт, большое спасибо за объяснение! Я пытался проследить за вашим ответом, но все еще проблема, я не упомянул, что уже использую FOSUserBundle,

my 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 в публичных брандмауэрах (но я должен это делать вообще?), Он выдает исключение You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.

Ответы [ 3 ]

7 голосов
/ 21 января 2012

Проверяли ли вы свой security.yml для:

factories:
    - "%kernel.root_dir%/../vendor/bundles/FOS/FacebookBundle/Resources/config/security_factories.xml"

Это важно, потому что оно оплачивает недостающие опции для услуги.

4 голосов
/ 18 ноября 2011

Хитрость заключается в том, чтобы иметь две отдельные записи в брандмауэре, одну для входа в форму и одну для входа в 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

1 голос
/ 29 июня 2012

Есть простой пример Bundle, который реализует FOSUserBundle и FOSFacebookBundle, если вы хотите посмотреть https://github.com/ollietb/OhFOSFacebookUserBundle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...