25

在 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. 

我使用的路线就这么简单:

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

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

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

    }).error(function(response){

    });

我已经尝试了十几个在 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();
      }
    });
    
  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);
    
  3. 我尝试在我的 app.js 文件(angularJS 配置)中添加它:

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

无论如何,我不知道还能做什么。我在网上找到的所有东西都不起作用。是否有可能与我使用 AngularJS 路由有关?我看不出这有什么重要的原因,但我有点猜不透了。

我的情况与此非常相似: Angular/Node/Express/Passport - Issues when connected to facebook(CORS)

提前致谢!

4

3 回答 3

33

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

解决方案是简单地将显示“使用_____ 登录”的按钮或文本设为链接。文字<a href="/auth/facebook"></a>链接。而已。

当然,在这个过程中我也遇到了很多其他的绊脚石和陷阱。我尝试不使用 passport.authenticate('facebook') 的默认中间件,但尝试将其包装在 a 中function(req, res, next){ ... },认为这会做一些事情,但事实并非如此。

于 2015-02-20T13:15:28.860 回答
3

我在 facebook 登录和 cors 方面也有问题,但在 NodeJS/Express 中没有 Passport,我的应用程序是 java(spring mvc)+ angular。我已经设法解决了修改我的初始 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);
    });
}

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

希望能帮助到你!

于 2014-10-15T07:29:05.170 回答
1

创建一个 html 标记来执行 GET 请求,facebook 不允许 XMLHttpsRequests。

像这样: <a href="http://localhost:8080/auth/facebook">sign in with facebook</a>

于 2018-02-28T14:05:25.380 回答