web-dev-qa-db-ja.com

Angular / Node / Express / Passportクロスドメインの問題-CORSPassportFacebook認証を有効にする

NodeJS/ExpressでPassportを使用してFacebookでユーザーを認証しようとすると、2日が経過し、100万人が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や他のフォーラムで見つけた12のソリューションを試しました。

  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-facebook(CORS)に接続する際の問題

前もって感謝します!

25
Larissa Leite

私はこの問題を抱えていて、解決策が見つからないと確信するところまで来ましたが、簡単なチュートリアルをもう一度見てみました( http://mherman.org/blog/2013/11/10/social- authentication-with-passport-dot-js / )は私のためにそれを解決しました。 AngularからNode.jsへのAPI呼び出しを行おうとしていました。これにより、サーバーで構成した内容に関係なく、常にXMLHttpRequestエラーが発生します。CORSかどうかは関係ありません。CORSはフィクスチャ-Chromeネットワークコンソールを開いた場合、GoogleやFacebook、またはサードパーティのサイトへのリクエストを変更することはできません-302リダイレクトからトリガーされましたこれはフロントエンドに返送されました。Angular.jsやその他のフレームワークには制御できないため、とにかくそのリクエストに「Access ControlAllowOrigin」を実際に追加することはできません。

解決策は、「_____でサインイン」というボタンまたはテキストをリンクにすることです。リテラル_<a href="/auth/facebook"></a>_リンク。それでおしまい。

もちろん、その過程で他の多くのつまずきや落とし穴にも遭遇しました。 passport.authenticate( 'facebook')にデフォルトのミドルウェアを使用しないようにしましたが、何かを行うと考えてfunction(req, res, next){ ... }でラップしようとしましたが、そうではありません。

31
Gary

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";
};

それが役に立てば幸い!

3
Horia Ion

代わりに、GETリクエストを実行するためのhtmlタグを作成します。FacebookはXMLHttpsRequestsを許可していません。

そのようです: <a href="http://localhost:8080/auth/facebook">sign in with facebook</a>

1
Matt Pengelly