web-dev-qa-db-fra.com

Problèmes de domaine croisé angulaire/noeud/express/passeport - Activer l'authentification Facebook du passeport CORS

Cela fait deux jours et un million de tentatives d'activation de CORS lors de la tentative d'authentification d'un utilisateur avec Facebook à l'aide de Passport dans NodeJS/Express.

L'erreur que je reçois sur Chrome est la suivante:

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. 

Les itinéraires que j'utilise sont aussi simples que cela:

// =====================================
// 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'
    }));

Voici comment la route est appelée sur mon fichier angularJS (j'ai également essayé de définir withCredentials: true):

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

    }).error(function(response){

    });

J'ai essayé une douzaine de solutions que j'ai trouvées ici sur StackOverflow et d'autres forums.

  1. J'ai essayé d'ajouter ceci avant les itinéraires sur les fichiers 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. J'ai essayé d'ajouter ceci sur le fichier server.js (notez que j'ai changé l'en-tête en setHeader mais j'ai essayé les deux):

    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. J'ai essayé d'ajouter ceci sur mon fichier app.js (configurations angularJS):

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

En tout cas, je ne sais pas quoi faire d'autre. Tout ce que j'ai trouvé en ligne n'a pas fonctionné. Y at-il une chance que cela ait quelque chose à voir avec mon utilisation du routage AngularJS? Je ne vois pas pourquoi cela aurait de l'importance, mais je suis un peu à court de suppositions.

Ma situation est très similaire à celle-ci: Angular/Node/Express/Passport - Problèmes de connexion à Facebook (CORS)

Merci d'avance!

25
Larissa Leite

J'avais ce problème et j'étais presque persuadé que je ne pouvais pas trouver de solution, mais je visais encore un simple tutoriel ( http://mherman.org/blog/2013/11/10/social-authentication- with-passport-dot-js/ ) me l'a résolu. J'essayais de faire un appel d'API de Angular à Node.js, ce qui vous apportera toujours ces erreurs XMLHttpRequest malgré ce que vous configurez sur le serveur, CORS ou non! CORS n’est pas à la hauteur - si vous ouvrez votre console réseau Chrome, vous constaterez que votre demande adressée à Google, à Facebook ou à tout autre site tiers est hors de votre contrôle. Elle a été déclenchée par une redirection 302 renvoyée à votre interface, quelque chose que Angular.js ou tout autre framework n’a aucun pouvoir à contrôler, vous ne pouvez donc pas vraiment ajouter "Access Control Allow Origin" à cette demande de toute façon.

La solution consiste simplement à transformer le bouton ou le texte "Connecter avec _____" en LINK. Un lien littéral <a href="/auth/facebook"></a>. C'est tout.

Bien sûr, j'ai également rencontré beaucoup d'autres obstacles et pièges dans le processus. J'ai essayé de ne pas utiliser le middleware par défaut pour passport.authenticate ('facebook'), mais j'ai essayé de l'envelopper dans une function(req, res, next){ ... }, pensant que cela ferait quelque chose, mais ce n'est pas le cas.

28
Gary

J'ai également eu un problème avec Facebook login et cors mais pas avec Passport dans NodeJS/Express, Mon application est Java (spring mvc) + angular. J'ai réussi à passer le problème de la modification de ma fonction de connexion initiale au fb: 

$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);
    });
}

avec

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

J'espère que ça aide!

3
Horia Ion

Créez une balise html pour faire la demande GET à la place. Facebook n'autorise pas XMLHttpsRequests.

Comme ceci: <a href="http://localhost:8080/auth/facebook">sign in with facebook</a>

0
Matt Pengelly