关于node.js:req.session.passport为空,未调用deserializeUser – ExpressJS,Passport

req.session.passport is empty, deserializeUser not called - ExpressJS, Passport

我在Passport / ExpressJS中使用会话时遇到问题。

当我记录req.session时,我可以看到护照是{}

1
2
3
4
5
6
7
{ cookie:
 { path: '/',
  _expires: Mon Sep 29 2014 19:37:16 GMT-0300 (BRT),
  originalMaxAge: 3594522,
  httpOnly: true,
  secure: true },
passport: {} }

此外,我正在使用Facebook进行身份验证,并且未调用passport.deserializeUser
这是我的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
    passport.use(new FacebookStrategy({

    // pull in our app id and secret from our auth.js file
    clientID        : configAuth.facebookAuth.clientID,
    clientSecret    : configAuth.facebookAuth.clientSecret,
    callbackURL     : configAuth.facebookAuth.callbackURL

},

// facebook will send back the token and profile
function(token, refreshToken, profile, done) {

    // asynchronous
    process.nextTick(function() {

        console.log("profile" + profile.id);
        console.log("profile.name"+profile.name.givenName)

        // find the user in the database based on their facebook id
        User.findOne({ 'facebook.id' : profile.id }, function(err, user) {

            // if there is an error, stop everything and return that
            // ie an error connecting to the database
            if (err)
                return done(err);

            // if the user is found, then log them in
            if (user) {
                //returning undefined
                //console.log(user.name +"" + user.email);
                return done(null, user); // user found, return that user
            } else {
                // if there is no user found with that facebook id, create them
                var newUser = new User();

                // set all of the facebook information in our user model
                newUser.facebook.id    = profile.id; // set the users facebook id
                newUser.facebook.token = token; // we will save the token that facebook provides to the user
                newUser.facebook.name  = profile.name.givenName + ' ' + profile.name.familyName; // look at the passport user profile to see how names are returned
                newUser.facebook.email = profile.emails[0].value; // facebook can return multiple emails so we'll take the first

                // save our user to the database
                newUser.save(function(err) {
                    if (err)
                        throw err;

                    // if successful, return the new user
                    return done(null, newUser);
                });
            }

        });
    });

}));

// used to serialize the user for the session
passport.serializeUser(function(user, done) {
    console.log("serialize");
    done(null, user.id);
});

// used to deserialize the user
passport.deserializeUser(function(id, done) {
    console.log("deserialize");
    User.findById(id, function(err, user) {
        console.log(user);
        done(err, user);
    });
});

我已经尝试将两种方法都移到了开头,但它没有任何区别。 passport.serializeUser被称为罚款。

这是我初始化passport的地方:

1
2
3
4
5
app.use (cookieParser());
app.use(session({ secret: 'appsecret', saveUninitialized: true, cookie: { secure: true, maxAge: new Date(Date.now() + 3600000) }, key:'connect.sid' }));

app.use(passport.initialize());
app.use(passport.session());

这是我的route

1
2
3
4
5
6
7
8
9
10
11
12
13
// =====================================
// 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'
    }));

有人可以帮我弄这个吗?

谢谢!


背景

对我来说,没有被调用deserializeUser和空护照对象的问题是跨域问题。当我从localhost发送ajax请求时:4200到localhost:1000个cookie和会话对我的Ember.js客户端不起作用。但是,Postman扩展收到了正确的答复。护照对象也正确地填充了数据。 User.deserializeUser被正确调用。

要解决这个问题,我必须设置正确的服务器端和客户端HTTP头。
服务器端(node.js + express + passport):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# The important part. Must go AFTER the express session is initialized
app.use passport.initialize()
app.use passport.session()

# Enable CORS
# X-Requested-With, X-AUTHENTICATION, X-IP
# https://stackoverflow.com/a/18290875/2166409
app.use (req, res, next) ->
  res.header 'Access-Control-Allow-Origin', 'http://localhost:4200'
  res.header 'Access-Control-Allow-Headers', 'Origin, X-Requested-With, X-AUTHENTICATION, X-IP, Content-Type, Accept'
  res.header 'Access-Control-Allow-Credentials', true
  res.header 'Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'
  next()

app.use '/api/v1', router

客户端:

如果使用jQuery将此添加到$ .ajax选项:

1
xhrFields: { withCredentials:true }

一切都按预期工作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
DESERIALIZE USER
{ id: '547fabf22a098ade53e6e48e',
  name: 'test',
  firstName: 'test',
  email: '[email protected]' }
LOGIN SUCCESS SESSION
{ cookie:
   { path: '/',
     _expires: Thu Dec 04 2014 20:26:52 GMT+0100 (CET),
     originalMaxAge: 3597205,
     httpOnly: false },
  passport:
   { user:
      { id: '547fabf22a098ade53e6e48e',
        name: 'test',
        firstName: 'test',
        email: '[email protected]' } } }

这些答案对我有帮助:关于Ember.js,jQuery.ajax。


对我来说,根本原因是快递会话中的cookie安全值。

1
2
3
4
5
6
app.use(require('express-session')({
    secret: 'crackalackin',
    resave: true,
    saveUninitialized: true,
    cookie : { secure : false, maxAge : (4 * 60 * 60 * 1000) }, // 4 hours
}));

在我的本地计算机上,我没有运行HTTP,因此当cookie.secure为true时,会话和用户对象为空。在开发模式下,安全性为假,它可以正常工作。


我的解决方案是在链接我网站的不同页面时保持一致。

用"www。"前缀链接的URL同时验证哪里没有'www。'链接到该前缀页面时将启动一个新会话。
您可以使用cookie查看器进行检查,看看这两个选项中是否有多个cookie。