6

connectを使用してパスポートをnodejsサーバーに統合しようとしていますが、正しく統合できないようです。すべてのガイド/例でexpressJSを使用しているため、コードを再フォーマットして自分のコードで動作するように最善を尽くしましたが、動作させることができないようです。関連する部分は以下のとおりです。何が問題なのか、誰かアドバイスはありますか?passport.authenticate()が呼び出されていないようです(少なくとも、Facebook認証コールバック内のconsole.logメッセージは出力されません)。私は現在データベースに何も保存していないので、問題は私が見逃している本当に単純なものであることが望まれます。

頭に浮かぶ唯一のことは、Facebookの潜在的なコールバックです。これはローカルホストのURLです(私はまだこれをローカルで開発しているため)。私は(純粋にローカルインスタンスからの)everyauthを使用してFacebookで問題なく認証できましたが、passportJSが対処しているように見えるさまざまな問題があったため、passportJSに切り替えました。

passport = require('passport');
  fpass = require('passport-facebook').Strategy;

passport.serializeUser(function(user,done){
    done(null, user);
});
passport.deserializeUser(function(obj,done){
    done(null,obj);
});

passport.use(new fpass({
        clientID:'facebook app id',
        clientSecret:'facebook app secret',
        callbackURL:'http://localhost:3000/auth/facebook/callback'
    },
    function(accessToken, refreshToken, fbUserData, done){
        console.log('got here');
        return done(null,fbUserData);
    }
));



    function checkLoggedIn(req, res, next){
        console.log("req.user: " + req.user);
        if(req.user)
            next();
        else{
            console.log('\nNot LOGGED IN\n');
            if(req.socket.remoteAddress || req.socket.socket.remoteAddress == '127.0.0.1'){
                var folder,contentType;
                console.log('req url = '+req.url);
                if(req.url == '/'){
                    folder = __dirname + '/landingPage.html';
                    contentType = 'text/html';
                }
                else if(req.url == '/auth/facebook'){
                    passport.authenticate('facebook');
                    return;
                }
                else if(req.url == '/auth/facebook/callback'){
                    passport.authenticate('facebook', {failureRedirect: '/failbook', successRedirect:'/'});
                    return;
                }
                if(folder){
                    console.log('got to folder part\n\n');
                    fs.readFile(folder, function(error, content){
                      if(error){
                        res.writeHead(500);
                        res.end();
                      }
                      else{
                        res.writeHead(200, {'Content-Type': contentType});
                        res.end(content);
                      }
                    });
                  }
                    else{ res.writeHead(500); res.end();}
            }
            else {res.writeHead(500); res.end();}
        }
    }

  connect.createServer(
    connect.cookieParser(),
    connect.bodyParser(),
    connect.session({secret:'wakajakamadaka'}),
    passport.initialize(),
    passport.session(),
    checkLoggedIn).listen(8888);
  console.log('Server has started.');
}

誰かアドバイスがありますか、私がしていることにグリッチがありますか?私の他の2つの選択肢は、everyauthに戻ってそこで何が起こっているのかを理解するか、ExpressJSに切り替えることですが、どちらのオプションも使用したくありません。

最高、
サーミ人

4

1 に答える 1

8

passport.authenticateExpressreqで呼び出されるミドルウェアチェーンで通常使用される関数を返します。res

これは、他のミドルウェアまたは関数などのルートハンドラー内でスタンドアロンで機能しますが、、、でcheckLoggedIn返された関数を明示的に呼び出し、要求を処理できるようにする必要があります。reqresnext

else if(req.url == '/auth/facebook'){
  // NOTE: call the function returned to process the request
  passport.authenticate('facebook')(req, res, next);
  return;
}

そうでなければよさそうだ。それがあなたを稼働させるかどうか私に知らせてください。


アップデート

Jaredはstackoverflowの外で私を少し助けてくれました、そして私たちは問題を完全に理解しました。この回答を更新して、見つかった新しい情報を含めます。


1) 1つの問題は、redirect()ミドルウェアがExpressには存在するが、Connectには存在しないことです(少なくとも現在のバージョンではありません)。connectを使用する場合は、PassportJSモジュールのauthenticate.jsの97行目を次のように変更する必要がありますreturn res.redirect(options.successRedirect);

var redirect = function(redirectionURL){
    res.writeHead(302, {'location':redirectionURL});
    res.end();             
}

return redirect(options.successRedirect);

注-上記は、コールバック関数コードoptions.successRedirectのと同じです。successRedirectこれはpassport.authenticate('facebook', {failureRedirect: '/failbook', successRedirect:'/'});私の質問のコードの行になります。


2)もう1つは、アプリでクラスターモジュールを使用していることです(上記のコードスニペットに表示されているものではありません)。これは、セッションデータがnodeJSアプリによって正しく読み取られていないことを意味し、問題が発生しました。この問題は、セッションを使用する他のすべての認証モジュール(everyauth、connect-authなど)を含む、セッションに依存するすべてのライブラリに影響します。解決策としてJaredを引用します。

クイック返信:クラスターを使用していますか、それとも複数のサーバーインスタンスを起動していますか?

その場合、セッションの組み込みのMemoryStoreは正しく機能しないため、次のようなものに切り替える必要があります: https ://github.com/visionmedia/connect-redis

または、ここにリストされている他のセッションストアの1つ: https ://github.com/senchalabs/connect/wiki

その理由は、元の要求を処理しなかったサーバーにアクセスすることになり、そのため、そのセッション情報が独自のメモリにないためです。これは、deserializeUserが100%呼び出されない場合に発生する可能性があることのように聞こえます。

これがここで成功する人の助けになることを願っています!

于 2012-06-13T00:01:29.153 に答える