2011-11-17 22 views
5

Necesito tener una url separada para el formulario de inicio de sesión simple (nombre de usuario/contraseña) que ya existe en/login, y alguna url como/login-via-facebook para iniciar sesión a través de FOSFacebookBundle oauth procedure.Cómo hacer una URL separada para iniciar sesión a través de Facebook usando FOSFacebookBundle en Symfony2

Ahora no puedo entender cómo desencadenar el procedimiento de oauth-facebook por url, solo funciona si intento acceder a la url que figura en "access_control".

¡Gracias de antemano!


@Matt, muchas gracias por su explicación! He intentado seguir su respuesta, pero todavía tiene un problema, que no he mencionado que ya que el uso de FOSUserBundle,

mi 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` 

así, en este punto se produce una excepción: InvalidConfigurationException: Unrecognized options "fos_userbundle" under "security.firewalls.public" , y si cambio fos_userbundle a form_login en firewalls públicos (¿pero debo hacer esto en absoluto?), arroja una excepción You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.

+0

he añadido un seguimiento de mi respuesta. – Matt

Respuesta

4

El truco consiste en tener dos entradas separadas en su firewall, una para el inicio de sesión de formulario y otra para el inicio de sesión de Facebook Pero en mi caso, tengo una sola URL de inicio de sesión donde el usuario puede iniciar sesión usando sus credenciales o hacer clic en una conexión de Facebook para autenticarse a través de la API de Facebook OAuth2 usando el FOSFacebookBundle. Aquí una muestra de mi archivo security.yml config para hacer este trabajo:

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] 

Y aquí una muestra de mi archivo routing.yml que se utiliza para definir rutas de seguridad requeridas para hacer este trabajo:

# 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 } 

Utilizando el security.yml antes, el mecanismo de seguridad verificará si el usuario inició sesión utilizando el formulario antes de que el usuario inicie sesión con Facebook. Esto se debe a que el orden en el que los proveedores se definen en el chain_provider. En cada solicitud, el FOSFacebookBundle comprueba si hay una cookie de facebook oauth2, de ser así, intenta cargar a su usuario. Si no puede encontrar la cookie, el proceso de autenticación probará con otro proveedor, si está definido después del proveedor de Facebook.

En su caso, cuando el usuario intenta ir a una url protegida (en access_control), se muestra la página de inicio de sesión de facebook y se autentica, luego se lo redirige a su sitio, se encuentra la cookie y el usuario se autentica con éxito por el FOSFacebookBundle. Para activar manualmente el proceso de autenticación, coloque un botón de Facebook Connect en su sitio, luego, en javascript, redirige al usuario a otra página de su sitio. De esta forma, la cookie será configurada por el botón de conexión y el FOSFacebookBundle lo autenticará en la próxima solicitud. Lo que hago es redirigir al usuario a la ruta login_check para facebook en javascript cuando el botón facebook connect ha sido exitoso. De esta forma, el mecanismo de seguridad lo redireccionará donde se indique en la configuración de seguridad.

Espero que esto lo ayude a lograr lo que desea. No haga clic para hacer más preguntas si algo no está claro.

@ Seguimiento # 1

De hecho, no se puede poner bajo el nodo fos_userbundlepublic en la configuración del cortafuegos, ya que no es una opción válida.La cadena fos_userbundle se utiliza para hacer referencia a la clase UserProvider FOSUserBundle. Nunca utilicé este paquete, pero al leer la documentación, debe usar form_login. Puede consultar la documentación de FOSUserBundle en Step #5 y más abajo. El error que menciona es extraño porque le dice que el cortafuegos no maneja el login_path, pero es el caso, ya que el cortafuegos hace coincidir cualquier cosa que comience con un / (^/). No estoy seguro de qué está yendo mal pero vas en la dirección correcta. Use form_login y trate de verificar por qué no funciona desde allí.

Saludos,
Matt

+0

muchas gracias, he editado la pregunta, por favor, mira si tienes algo de tiempo. – synthetic

7

¿verificó su security.yml para:

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

Es importante porque va a cargar las opciones que faltan para el servicio.

+0

Esto realmente resolvió uno de mis errores. Gracias por su entrada en este hilo – Hezad

1

Hay un simple paquete de ejemplo que implementa tanto FOSUserBundle y FOSFacebookBundle si desea buscar https://github.com/ollietb/OhFOSFacebookUserBundle

+0

¡Gracias por publicar esto! Creé una aplicación completa de Symfony 2.1 usando tu código: https://github.com/meonkeys/symfony21-dual-auth –

+0

Ese repositorio de git se mudó. Nueva URL: https://github.com/meonkeys/symfony2-dual-auth –

Cuestiones relacionadas