Facebook回调函数的CORS错误

Posted

技术标签:

【中文标题】Facebook回调函数的CORS错误【英文标题】:CORS error with Facebook callback function 【发布时间】:2014-08-18 23:28:12 【问题描述】:

我有以下代码:

app.js:

var passport = require('passport')
  , FacebookStrategy = require('passport-facebook').Strategy
  , ...
passport.serializeUser(function(user, done) 
  console.log('serializing user')
  done(null, user);
)
passport.deserializeUser(function(obj, done) 
  console.log('deserializeUser')
  done(null, obj)
)
passport.use(new FacebookStrategy(
    clientID: FBAPP.id,
    clientSecret: FBAPP.secret,
    callbackURL: 
      "http://www.mylocal.com:3000/auth/facebook/callback"
  ,
  function(accessToken, refreshToken, profile, done) 
    // asynchronous verification, for effect...
    process.nextTick(function () 
      return done(null, profile)
    )
  
))
app.get('/auth/facebook', passport.authenticate('facebook', 
   scope: ['email, user_likes, user_photos, publish_actions'] ))
app.get('/auth/facebook/callback', 
passport.authenticate('facebook',  
  successRedirect: '/loginsuccess', failureRedirect : '/loginfail' ))
app.get('loginsuccess', function(req, res) 
   console.log('Login success')
  res.send(200, 'ok')
)
app.get('/loginfail', function(req, res) 
  console.log('Login error')
  res.send(401, 'error')
)

棱角部分:

factory('FacebookFactory', ['$http', '$q', function($http, $q) 
    var get = function() 
        var deferred = $q.defer();
        $http(method: 'GET', url: '/auth/facebook').
        success(function(data, status, headers, config) 
            deferred.resolve(data);
        ).
        error(function(data, status, headers, config) 
            deferred.reject(data);
        );
        return deferred.promise;
    ;
    return 
        get: get
    ;
])

我总是遇到这个错误并尝试了几次但没有成功。

XMLHttpRequest cannot load https://www.facebook.com/dialog/oauth?
response_type=code&redirect_uri=http%…
user_likes%2C%20user_photos%2C%20publish_actions&client_id=xxxxxxxxxxx. 
No 'Access-Control-Allow-Origin' header 
is present on the requested resource. Origin '[basic
links]http://www.mylocal.com:3000' is therefore 
not allowed access. 

有人知道吗?我确实仅在 Angular 中尝试过,但它在 Safari 中不起作用,但在 Chrome 和 FF 中却可以完美运行。

www.mylocal.com:3000 = localhost:3000

【问题讨论】:

同样的问题!你找到解决办法了吗? 事实上没有。除了在 Facebook 端使用新应用程序从头开始。它有效,但比较没有显示任何差异。 你可能需要使用 $http.jsonp() 吗?只是猜测。 【参考方案1】:

您将找不到使用客户端语言的解决方案,因为这构成了可能被用作恶意攻击的跨域请求。所以基本上 Facebook 端点需要有一个 Access-Control-Allow-Origin 标头块集,我认为他们不会很快这样做。我经常使用 API,并且经常必须在我的端点中设置这些标头,以便我的客户端可以从 localhost 或 dev url 连接:

    if (isset($_SERVER['HTTP_ORIGIN'])):
        header("Access-Control-Allow-Origin: $_SERVER['HTTP_ORIGIN']");
        header('Access-Control-Allow-Credentials: true');
        header('Access-Control-Max-Age: 86400');
    endif;
    if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS'):
        if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])):
            header('Access-Control-Allow-Methods: GET, POST, OPTIONS, DELETE, PUT');
        endif;
        if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])):
            header("Access-Control-Allow-Headers: $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']");
        endif;
        exit(0);
    endif;

你也可以在你的 $http 代理中试试这个:

        var promise = $http(
            method: 'POST',
            url: 'url_to_api',
            data: params,
            headers: 
                'Access-Control-Allow-Origin': true,
                'Content-Type': 'application/json'
            
        ).success(function (data, status, headers, config) 
            return data;
        );

【讨论】:

【参考方案2】:

我在后端有一个带有 express 的 Angular 应用程序。当我单击带有此 html 的按钮时:

<input type="button" ng-click="socialLogIn('facebook')" class="modal-input" value="Sign in with Facebook">

它给了我一个 CORS 错误:

$scope.socialLogIn = function (social) 
    return $http.get ('/auth/'+social).success (function (data) 
        auth.saveToken (data.token);  // write data to local storage
    );

问题是,我想取回令牌,以便将其保存在 localStorage 中。我确实解决了它,但解决方案是迂回的。在 socialLogIn 函数中,我打开了一个新窗口:

$scope.socialLogIn = function (social) 
    var url = 'http://' + $window.location.host + '/auth/' + social;
    $window.open(url);
;

在快递后端,在我从 Facebook 或 Google 获得“东西”并创建令牌后,我发回了一些保存令牌的代码,重新加载父窗口并自行关闭:

function loginReturn (res, token) 
  var returnString = '' +
          '<!DOCTYPE html>\n' +
          '<html>\n' +
            '<head>\n' +
              '<meta charset="UTF-8">\n' +
              '<title>Login</title>\n' +
            '</head>\n' +
            '<body>\n' +
            '<script type="text/javascript">\n' +
              'window.localStorage[\'token\']  = \''+token+'\';\n' +
              'window.opener.location.reload(false);\n' +
              'window.close();\n' +
            '</script>\n' +
            '</body>\n' +
          '</html>'; 

  res.send(returnString);
;

【讨论】:

以上是关于Facebook回调函数的CORS错误的主要内容,如果未能解决你的问题,请参考以下文章

用户取消应用请求后,Laravel 5 Socialite Facebook 登录错误处理回调

使用命名函数作为 jQuery 中 $.getJSON 的回调来满足 Facebook 请求签名需求

Facebook 分享回调不起作用

节点 cors 捕获中间件回调错误

Javascript的Nodejs的程序错误:回调必须为函数怎么解决?

使用 Angular 向 facebook oauth 发出 CORS 问题