Angular/Node/Express/Passport跨域问题 - 启用CORS Passport Facebook身份验证

Lar*_*ite 25 node.js cors angularjs passport-facebook passport.js

在尝试使用NodeJS/Express中的Passport对Facebook用户进行身份验证时,已经有两天和一百万次尝试启用CORS.

我在Chrome上遇到的错误是:

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. 
Run Code Online (Sandbox Code Playgroud)

我使用的路线很简单:

// =====================================
// 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'
    }));
Run Code Online (Sandbox Code Playgroud)

这是在我的angularJS文件上调用路由的方式(我也尝试过设置withCredentials:true):

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

    }).error(function(response){

    });
Run Code Online (Sandbox Code Playgroud)

我在StackOverflow和其他论坛上尝试了十几个解决方案.

  1. 我尝试在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();
      }
    });
    
    Run Code Online (Sandbox Code Playgroud)
  2. 我尝试在server.js文件中添加这个(请注意我将标题更改为setHeader但我已尝试过两种方法):

    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);
    
    Run Code Online (Sandbox Code Playgroud)
  3. 我尝试在app.js文件中添加这个(angularJS配置):

    $httpProvider.defaults.useXDomain = true;
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
    $httpProvider.defaults.withCredentials = true;
    
    Run Code Online (Sandbox Code Playgroud)

无论如何,我不知道还能做什么.我在网上发现的一切都不起作用.有可能它与我使用AngularJS路由有关吗?我没有看到任何理由为什么这很重要,但我有点用尽了猜测.

我的情况非常类似于: Angular/Node/Express/Passport - 连接到facebook时的问题(CORS)

提前致谢!

Gar*_*ary 31

我遇到了这个问题,几乎达到了我确信我找不到解决方案的程度,但又看了一个简单的教程(http://mherman.org/blog/2013/11/10/social-authentication-with- passport-dot-js /)为我解决了这个问题.我试图从Angular到Node.js进行API调用,无论你在服务器上配置了什么,CORS都会给你带来那些XMLHttpRequest错误!CORS不是固定设施 - 如果您打开Chrome网络控制台,您会发现您对Google或Facebook或任何第三方网站的请求无法控制更改 - 它是由302重定向触发的,该重定向已发送回你的前端,Angular.js或任何其他框架无法控制的东西,因此无论如何你无法真正为该请求添加"访问控制允许来源".

解决方案只是使按钮或文本"登录_____"链接.文字<a href="/auth/facebook"></a>链接.而已.

当然,我还遇到了很多其他绊脚石和陷阱.我试图不使用passport.authenticate('facebook')的默认中间件,但试图把它包装成一个function(req, res, next){ ... },以为会做某事,但事实并非如此.

  • @AdamZerner,这只是因为您尝试的链接无效"前端URL"(或者说不是角度路由器识别的URL),那就是$ urlRouterProvider.otherwise('/'); 这个解决方案实际上很简单,你只需要在一个标签上加上'target ="_ self"',这将绕过角度路由器. (2认同)
  • 如何将用户对象或令牌发送回前端? (2认同)

Hor*_*Ion 3

我也遇到了 facebook 登录和 cors 的问题,但 NodeJS/Express 中的 Passport 没有问题,我的应用程序是 java(spring mvc)+ Angular。我已经成功解决了修改我的初始 Facebook 登录功能的问题:

$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);
    });
}
Run Code Online (Sandbox Code Playgroud)

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

希望能帮助到你!