javascript - session 不是持久的 [PASSPORT]

标签 javascript node.js mean-stack oauth-2.0 passport.js

我正在尝试通过 OAuth 2.0 实现登录,但是我无法使我的 session 持续存在,似乎在用户经过身份验证后,他们的 session 就消失了。此外,该应用程序似乎在回调函数中的重定向处卡在了 paths/bnetauth.js 中。

这些是我使用 Passport 的文件

app.js

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
//TOOLS
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session'); //Persistant sessions
var passport = require('passport');
//REQUIRE MODELS
require('./models/News');
require('./models/Application');
//REQUIRE ROUTES
var bnetauth = require('./routes/bnetauth')(passport);
var api = require('./routes/api');
var public = require('./routes/public');
var admin = require('./routes/admin');

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/karatechop');

require('./config/passport')(passport);

var app = express();

app.use(express.static('views'));
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use(session({
    secret: 'ilovescotchscotchyscotchscotch', // session secret
    resave: true,
    saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());

//Use Routes
app.use('/auth', bnetauth)
app.use('/api', api);
app.use('/admin', admin);
app.use('/', public);


// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
});

module.exports = app;

routes/bnetauth.js(通过battle.net登录,因此得名bnetauth)

var express = require('express');
var router = express.Router();


module.exports = function(passport) {

    router.get('/bnet',
        passport.authenticate('bnet'));

    router.get('/bnet/callback',
        passport.authenticate('bnet', {
            failureRedirect: '/' }),
        function(req, res, next){
            console.log('Authenticated: ' + req.isAuthenticated())
           ####THIS IS WHERE IT GETS STUCK####
            res.redirect('https://localhost:3000/');
        });

配置/passport.js

var BnetStrategy = require('passport-bnet').Strategy;


var BNET_ID = 'hidden'
var BNET_SECRET = 'hidden'

var User = require('../models/user')


// expose this function to our app using module.exports
module.exports = function(passport) {
    console.log('Entering passport')
    // =========================================================================
    // passport session setup ==================================================
    // =========================================================================
    // required for persistent login sessions
    // passport needs ability to serialize and unserialize users out of session

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

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

    passport.use(new BnetStrategy({
        clientID: BNET_ID,
        clientSecret: BNET_SECRET,
        region: 'eu',
        callbackURL: "https://localhost:3000/auth/bnet/callback"
    }, function(accessToken, refreshToken, profile, done) {
        console.log(profile)
        console.log(accessToken)
        User.findOne({id: profile.id}, function(err, user){
            console.log("Trying!")
            if(err)
                return done(err);

            if(user) {
                return done(null, user);
            } else {
                var newUser = new User();

                newUser.id = profile.id,
                newUser.token = accessToken,
                newUser.battle_tag = profile.battletag

                newUser.save(function(err) {
                    if (err)
                        throw err;

                    return done(null, newUser);
                });
            }
        });
    }));
};

    return router;
}

最佳答案

我找到了问题的解决方案!

问题出在 config/passport.js 中的序列化和反序列化函数

在我的用户模型中,我有两种形式的 id。

  1. mongo申请的_id
  2. 我从 Battle.net 传回给我的用户对象中保存的 ID(这是 Battle.net 上用户的 ID)。

在序列化中,将用户序列化到 session 时使用的 ID 将是 Battle.net ID(因为我调用的是 user.id 而不是 user._id

然后,在从用户对象提取数据时的反序列化中,我使用了 mongo 的 findById 函数,该函数使用 ._id (这与 .id 完全不同)在我的用户对象中,因此它返回'undefined'

将序列化函数中的 .id 更改为 ._id 解决了我的问题, session 现在可以正常工作并且是持久的。

关于javascript - session 不是持久的 [PASSPORT],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40960154/

相关文章:

javascript - 在 HTML5 Canvas 中创建表格

javascript - streams2 Writable - 有没有办法定义 "_end"函数?

javascript - 是否可以将 Realm 与 A​​ngular 2 一起使用?

node.js - PLIVO 短信发件人 ID 问题

node.js - 为什么密码和盐会自动出现在 MEAN STACK 中?

javascript - Ajax 响应未显示在页面上

c# - 存在临时数据未清除的问题

javascript - 是否可以将 JS 函数导入 js.erb 文件?

node.js - 使用 Node.js 和 Mongoose 将查询结果保存到模型/模式的属性

node.js - 无法连接到数据库MongoParseError : Unescaped at-sign in authority section