6

我正在尝试使用 connect 将护照集成到我的 nodejs 服务器中,但似乎无法正确执行。所有指南/示例都使用 expressJS,所以我尽力重新格式化代码以使用我的代码,但我似乎无法让它工作。相关部分写在下面。有人对可能是什么问题有任何建议吗?passport.authenticate() 似乎从未被调用(至少 facebook 身份验证回调中的 console.log 消息从不打印)。我目前没有将任何内容保存到数据库中,所以希望这个问题应该是我刚刚错过的非常简单的事情。

唯一想到的是我对 facebook 的潜在回调,它是一个 localhost 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.');
}

有人有什么建议或看到我在做什么吗?我的另外两个选择是切换回everyauth 并弄清楚那里发生了什么,或者切换到 ExpressJS,但我宁愿不使用其中任何一个选项。

最好的,
萨米

4

1 回答 1

8

passport.authenticate返回一个通常在中间件链中使用的函数,该函数reqresExpress 调用。

它将在其他中间件或路由处理程序(例如您的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)一个问题显然是在 Express 中存在 redirect() 中间件,但在 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)另一个是我在我的应用程序中使用集群模块(不是我上面的代码片段中显示的东西)。这意味着 nodeJS 应用程序没有正确读取会话数据,这导致了我的问题。此问题将影响任何依赖会话的库,包括所有其他使用会话的身份验证模块(例如everyauth、connect-auth 等)。我将引用 Jared 的解决方案:

快速回复:您是使用集群还是启动多个服务器实例?

如果是这样,会话的内置 MemoryStore 将无法正常工作,您需要切换到如下内容: https ://github.com/visionmedia/connect-redis

或此处列出的其他会话存储之一: https ://github.com/senchalabs/connect/wiki

原因是您最终会遇到一个不提供原始请求的服务器,因此它自己的内存中没有该会话信息。如果没有 100% 的时间调用 deserializeUser,这听起来可能会发生什么。

希望这对在这里成功的人有所帮助!

于 2012-06-13T00:01:29.153 回答