2014-09-25 12 views
21

Sono stati due giorni e un milione di tentativi per abilitare CORS quando si tenta di autenticare un utente con Facebook utilizzando Passport in NodeJS/Express.Problemi di dominio incrociato Angolare/Nodo/Express/Passport - Abilitare l'autenticazione Facebook CORS Passport

L'errore che ottengo su Chrome è questo:

XMLHttpRequest cannot load https://www.facebook.com/dialog/oauth?response_type=code&redirect_uri=http%…%3A8080%2Fauth%2Ffacebook%2Fcallback&scope=email&client_id=598171076960591. 
No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'http://localhost:8080' is therefore not allowed access. 

I percorsi che uso sono così semplice come sembra:

// ===================================== 
// FACEBOOK ROUTES ===================== 
// ===================================== 
// route for facebook authentication and login 

app.get('/auth/facebook', passport.authenticate('facebook', { scope : 'email' })); 

// handle the callback after facebook has authenticated the user 
app.get('/auth/facebook/callback', 
    passport.authenticate('facebook', { 
     successRedirect : '/home', 
     failureRedirect : '/login' 
    })); 

In questo modo il percorso viene chiamato sul mio file angularJS (I 'ho anche provato withCredentials impostazione: true):

$http.get('/auth/facebook') 
    .success(function(response) { 

    }).error(function(response){ 

    }); 

che ho provato una dozzina di soluzioni che ho trovato qui su StackOverflow e altri forum.

  1. ho provato ad aggiungere questo sul davanti ai miei percorsi sui file routes.js:

    app.all('*', function(req, res, next) { 
        res.header('Access-Control-Allow-Origin', '*'); 
        res.header("Access-Control-Allow-Headers", "Content-Type,X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name"); 
        res.header('Access-Control-Allow-Methods', 'GET,POST,PUT,HEAD,DELETE,OPTIONS'); 
        res.header('Access-Control-Allow-Credentials', true); 
    
        if ('OPTIONS' == req.method) { 
         res.send(200); 
        } else { 
         next(); 
        } 
    }); 
    
  2. Ho provato ad aggiungere questo su file di server.js (notare che ho cambiato intestazione SetHeader ma io 'ho provato entrambi):

    app.use(function(req, res, next) { 
        res.setHeader('Access-Control-Allow-Origin', '*'); 
        res.setHeader('Access-Control-Allow-Headers', 'Content-Type,X-Requested-With'); 
        res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,HEAD,DELETE,OPTIONS'); 
        res.setHeader('Access-Control-Allow-Credentials', true); 
    
        if ('OPTIONS' == req.method) { 
        res.send(200); 
        } else { 
        next(); 
        } 
    
    }); 
    
    require('./app/routes.js')(app, passport); 
    
  3. ho provato ad aggiungere questo sul mio file app.js (angularJS configurazioni):

    $httpProvider.defaults.useXDomain = true; 
    delete $httpProvider.defaults.headers.common['X-Requested-With']; 
    $httpProvider.defaults.withCredentials = true; 
    

In ogni caso, non so cos'altro fare. Tutto ciò che ho trovato online non ha funzionato. C'è una possibilità che abbia qualcosa a che fare con me usando AngularJS Routing? Non vedo alcuna ragione per cui ciò possa avere importanza, ma mi sono perso le supposizioni.

La mia situazione è molto simile a questa: Angular/Node/Express/Passport - Issues when connecting to facebook(CORS)

Grazie in anticipo!

+0

possibile duplicato di [? Come consentire CORS in veloce/NodeJS] (http://stackoverflow.com/questions/7067966/how-to-allow-cors-in-express -nodejs) –

+0

So che ci sono molte domande simili, e ho visto quasi tutte. Sfortunatamente, nessuna delle soluzioni che ho provato ha funzionato finora ... –

+0

Non è possibile utilizzare contemporaneamente "Access-Control-Allow-Credentials: true" e "Access-Control-Allow-Origin: *" ". Per il tuo caso, dovresti impostare "Access-Control-Allow-Origin: localhost: 8080' anziché" * ". – wuct

risposta

3

Avevo anche un problema con l'accesso di Facebook e cors ma non con Passport in NodeJS/Express, la mia applicazione è java (spring mvc) + angular. Sono riuscito a passare sopra il problema modificando la mia funzione fb login iniziale:

$scope.loginWithFacebook = function() { 
    $http({ 
     method: 'GET', 
     url: 'auth/facebook', 
     dataType: 'jsonp' 
    }).success(function(data){ 
     console.log('loginWithFacebook success: ', data); 
    }).error(function(data, status, headers, config) { 
     console.log('loginWithFacebook error: ', data); 
    }); 
} 

con

$scope.loginWithFacebook = function() { 
    $window.location = $window.location.protocol + "//" + $window.location.host + $window.location.pathname + "auth/facebook"; 
}; 

Speranza che aiuta!

+0

Puoi spiegare perché il tuo cambiamento funziona? – mikestaub

+0

grazie, questo funziona: D – phamductri

+1

@mikestaub non è possibile chiamare api del server che comporterà 302 (reindirizzamento) dal front-end quindi sarà necessario inviare l'utente direttamente al server –

25

Avevo questo problema e ho raggiunto quasi il punto in cui ero convinto di non riuscire a trovare alcuna soluzione, ma guardando di nuovo un semplice tutorial (http://mherman.org/blog/2013/11/10/social-authentication-with-passport-dot-js/) l'ho risolto. Stavo cercando di effettuare una chiamata API da Angular a Node.js, che ti porterà sempre quegli errori XMLHttpRequest nonostante ciò che hai configurato sul server, CORS o no! CORS non è la soluzione: se hai aperto la tua console di rete Chrome, scoprirai che la tua richiesta a Google o Facebook o qualsiasi sito di terze parti è fuori dal tuo controllo di cambiare: è stata attivata da un reindirizzamento 302 che è stato inviato a il tuo frontend, qualcosa che Angular.js o qualsiasi altro framework non ha il potere di controllare, quindi non puoi davvero aggiungere "Access Control Allow Origin" a quella richiesta comunque.

La soluzione consiste semplicemente nel rendere il pulsante o il testo che dice "Accedi con _____" a un LINK. Un collegamento letterale <a href="/auth/facebook"></a>. Questo è tutto.

Naturalmente, ho anche incontrato molti altri ostacoli e trucchi nel processo. Ho provato a non utilizzare il middleware predefinito per passport.authenticate ('facebook'), ma ho provato a racchiuderlo in un function(req, res, next){ ... }, pensando che avrebbe fatto qualcosa, ma non è così.

+0

Sto usando UI-Router. Ho provato il collegamento, ma questo è preso da '$ urlRouterProvider.otherwise ('/');' e portarmi alla mia home page. qualche idea? –

+2

@AdamZerner, è semplicemente perché il link che hai provato non era valido "URL di frontend" (o non l'URL riconosciuto dal router angolare) ed è qui che $ urlRouterProvider.otherwise ('/'); kicked in. La soluzione è in realtà abbastanza semplice, è sufficiente aggiungere "target =" _ self "al tag a, che bypasserà il router angolare. – spiritwalker

+0

Ehi, mi sono bloccato sullo stesso identico problema della domanda originale. ** La combinazione della risposta di Gary e del commento dello spiritista ha risolto tutti i problemi relativi agli errori e ai reindirizzamenti CORS. Ha funzionato come un fascino. ** Grazie a te @Gary e spiritwalker. – Stuci

0

Creare un tag html per effettuare la richiesta GET invece, facebook non consente XMLHttpsRequests.

Come così: <a href="http://localhost:8080/auth/facebook">sign in with facebook</a>

Problemi correlati