首页 文章

req.session.passport和req.user空白,并且req.isAuthenticated在使用passport-facebook初次成功登录后返回false

提问于
浏览
8

在初次成功登录Facebook并使用passport-facebook 1.0.3和express 4.6.1登录重定向回调后,req.session.passport和req.user包含序列化调用期间设置的值(我从stragegy获得),但是在随后访问网站上的不同路由时,req.session.passport和req.user为空,req.isAuthenticated()返回false,因此在从FB初始成功登录后,所有其他路由上的ensureAuthentication方法都会失败 . 我没有使用集群设置,所以我相信内存存储足以处理这个,快速配置看起来很好(我的意思是订单),这是我的快速配置

configExpressApp.set('views',  './views');
configExpressApp.set('view engine', 'jade');
configExpressApp.use(morgan('dev'));
configExpressApp.use(cookieParser());
configExpressApp.use(bodyParser.urlencoded({
  extended: true,
}));
configExpressApp.use(bodyParser.json());
configExpressApp.use(expressSession({
  secret:'MyExpressSecret', 
  saveUninitialized: true,
  resave: true
}));
configExpressApp.use(passport.initialize());
configExpressApp.use(passport.session());
configExpressApp.use(methodOverride());
configExpressApp.use(express.static('./public'));

这是初始成功登录和重定向的req.session对象,req.user包含与req.session.passport.user相同的数据 .

{ cookie: 
   { path: '/',
     _expires: null,
     originalMaxAge: null,
     httpOnly: true },
  passport: 
   { user: 
      { _id: 53ce23e3121421f229a438f8,
        info: false,
        loginType: 'fb',
        fbId: 'MyId',
        name: 'Karthic Rao',
        email: 'kartronics85@yahoo.com'

        }
     }
}

这是我之前与策略内部的done()回调以及序列化调用内部关联的信息 . 在成功登录和回调之后,我使用res.redirect将用户重定向到不同的路由,但来自该路由的请求包含sessionID(所以我不认为它与会话存储的问题),但是req.user字段不存在(可能是因为passport.initialize()和passport.session()中间件没有找到要验证的请求)并且req.session.passport字段为空,这里是来自req的console.log的详细信息对象 .

sessionID: 'I9R1c3PIYgDW5OpWbNT7qb02Hn4lOeAB',
session: 
   { cookie: 
      { path: '/',
        _expires: null,
        originalMaxAge: null,
        httpOnly: true },
     passport: {} },

这是我的反序列化方法

passport.deserializeUser(function(user, done) {
    console.log('deserialize loginType facebook');
    db.collection("users").findOne({
        fbId: user.id
    }, function(err, docs) {
        console.log(docs);
        done(err, docs);
    });
});

这是我的序列化方法

passport.serializeUser(function (user, done) { 
    console.log(user);
    done(null, user);
});

这对我的开发造成了很大的障碍,我怎么能解决这个问题呢?

1 回答

  • 10

    好吧,如果你可以在你使用策略的地方添加代码(它应该在中间件中),这将为我们提供问题的完整视图,因为我们需要知道发送到 serializeUser 的对象 .

    (非常)基本上,当用户尝试进行身份验证时,事情就是这样发生的:

    • Passport尝试针对Facebook服务器对您的用户进行身份验证

    • 如果成功,则使用包含用户详细信息的对象调用回调函数(或successRedirect)

    • 然后,Passport调用 req.login 来存储有关会话中用户的一些信息

    • 然后调用 serializeUser 并有效地存储您在会话中指定的数据 .

    但是从您发布的代码中,我怀疑在您的 deserializeUser 中, user.id 未定义,因为存储在会话中的 user 对象使用名为 _id 而不是 id 的ID字段 .

    如果你改变了

    db.collection("users").findOne({
            fbId: user.id
    

    db.collection( “用户”) . findOne({
    fbId:user._id

    db.collection("users").findById(user._id, [fields],[options],[callback]);
    

    我认为它应该工作 .

    EDIT :我根据@ BrandonZacharie的评论编辑了我的答案,该评论指出了我的代码中的错误 .

相关问题