2011-11-17 12 views
5

Ho bisogno di avere un URL separato per il modulo di accesso semplice (username/password) che già esiste su/login, e alcuni url come/login-via-facebook per accedere tramite FOSFacebookBundle oauth procedure.Come creare un URL separato per il collegamento tramite Facebook utilizzando FOSFacebookBundle in Symfony2

Ora non riesco a capire come attivare la procedura oauth-facebook da url, funziona solo se provo ad accedere all'url che è elencato in "access_control".

Grazie in anticipo!


@ Matt, grazie mille per la spiegazione! Ho cercato di seguire la tua risposta, ma hanno ancora un problema, non ho detto che ho già utilizzando FOSUserBundle,

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

così, a questo punto viene generata un'eccezione: InvalidConfigurationException: Unrecognized options "fos_userbundle" under "security.firewalls.public" e se cambio fos_userbundle in form_login nei firewall pubblici (ma dovrei farlo affatto?), genera un'eccezione You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.

+0

ho aggiunto un follow-up alla mia risposta. – Matt

risposta

4

Il trucco è di avere due voci separate nel firewall, una per il login del form e una per il login di facebook. Ma nel mio caso, ho un unico URL di accesso in cui l'utente può accedere utilizzando le sue credenziali o fare clic su una connessione Facebook per autenticare tramite l'API OAuth2 di Facebook utilizzando lo FOSFacebookBundle. Ecco un esempio del mio file security.yml config per fare questo lavoro:

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] 

Ed ecco un esempio del mio file routing.yml che viene utilizzato per definire le rotte di sicurezza necessarie per fare questo lavoro:

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

Utilizzando la security.yml prima, il meccanismo di sicurezza controllerà l'utente che ha effettuato l'accesso usando il modulo prima che l'utente abbia effettuato l'accesso con Facebook. Questo perché l'ordine in cui i provider sono definiti nel chain_provider. Su ogni richiesta, il FOSFacebookBundle verifica se è presente un cookie di Facebook oauth2, in tal caso, prova a caricare l'utente. Se non riesce a trovare il cookie, il processo di autenticazione proverà con un altro provider, se definito dopo il provider di Facebook.

Nel tuo caso, quando l'utente tenta di accedere a un URL protetto (in access_control), viene visualizzata la pagina di accesso di Facebook e lui autentica, quindi viene reindirizzato al tuo sito, il cookie viene trovato e l'utente viene autenticato con successo dal FOSFacebookBundle. Per attivare manualmente il processo di autenticazione, posiziona un pulsante di connessione di Facebook sul tuo sito, quindi, in javascript, reindirizza l'utente a un'altra pagina del tuo sito. In questo modo, il cookie verrà impostato dal pulsante Connetti e lo FOSFacebookBundle lo autenticherà alla successiva richiesta. Quello che faccio, è di reindirizzare l'utente al percorso login_check per facebook in javascript quando il pulsante facebook connect ha avuto successo. In questo modo, il meccanismo di sicurezza lo reindirizzerà dove è indicato nella configurazione di sicurezza.

Spero che questo ti aiuterà a ottenere ciò che desideri. Non esitare a fare ulteriori domande se qualcosa non è chiaro.

@ Follow-up # 1

In effetti, non si può mettere fos_userbundle sotto il nodo public nella configurazione del firewall perché non è un'opzione valida.La stringa fos_userbundle viene utilizzata per fare riferimento alla classe UserProvider FOSUserBundle. Non ho mai usato questo pacchetto ma leggendo la documentazione, dovresti usare form_login. È possibile consultare la documentazione di FOSUserBundle in Step #5 e di seguito. L'errore che hai citato è strano perché ti dice che il login_path non è gestito dal firewall ma è il caso dal momento che il firewall corrisponde a qualsiasi cosa che inizia con un / (^/). Non sei sicuro di cosa stia andando male, ma stai andando nella giusta direzione. Usa form_login e prova a controllare perché non funziona da lì.

saluti,
Matt

+0

grazie mille, ho modificato la domanda, per favore guarda se hai tempo. – synthetic

7

Hai controllato la tua security.yml per:

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

E 'importante perché si caricherà le opzioni mancanti per il servizio.

+0

Questo ha effettivamente risolto uno dei miei bug. Grazie per il tuo contributo in questa discussione – Hezad

1

C'è un semplice esempio Bundle che implementa sia FOSUserBundle e FOSFacebookBundle se si desidera guardare https://github.com/ollietb/OhFOSFacebookUserBundle

+0

Grazie per aver pubblicato questo! Ho creato un'app completa di Symfony 2.1 usando il tuo codice: https://github.com/meonkeys/symfony21-dual-auth –

+0

Questo repository git si è spostato. Nuovo URL: https://github.com/meonkeys/symfony2-dual-auth –

Problemi correlati