首页 > 解决方案 > nodejs:身份验证期间出现“req.session.save 不是函数”错误

问题描述

我正在使用 PassportJS 对我的应用程序中的用户进行身份验证。用户登录后,会创建会话,但在重定向后不久,会话似乎再次变得未定义,因为它尚未保存。我在网上发现经常使用重定向,重定向在会话保存之前完成,所以就好像从未发生过身份验证一样。明显的解决方案是使用 req.session.save 函数,这样重定向只会在会话保存后发生。但是,我收到“TypeError:req.session.save 不是函数”的错误日志。有人可以帮忙吗?

这是我的 app.js 代码。

var express = require('express'),
      passport = require('passport'),
      session = require('express-session'),
      bodyParser = require('body-parser'),
      RedisStore = require('connect-redis')(session),
      redis = require('redis'),
      logger = require('morgan'),
      errorHandler = require('express-error-handler'),
      site = require('./site'),
      oauth2 = require('./oauth2'),
      port = process.env.PORT || 8080;

var app = express();

var redisClient = redis.createClient(8080, 'localhost');

// use sessions for tracking logins
app.use(session({
  secret: 'keyboard cat',
  resave: true,
  saveUninitialized: true,
  store: new RedisStore({
    client: redisClient,
    host: "pub-redis-14280.us-central1-1-1.gce.garantiadata.com",
    port: 12543,
    ttl: 260
   })
}));

app.use(logger('dev'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json({ type: 'application/json' }));

app.use(passport.initialize());
app.use(passport.session());
app.use(errorHandler({ dumpExceptions: true, showStack: true }));

// use ejs as file extension for views
app.set('view engine', 'ejs');
app.use(express.static(__dirname + '/views'));

// use passport
require('./auth');

// Account linking
app.get('/', site.index);
app.get('/login', site.loginForm);
app.post('/login', site.login);
app.get('/logout', site.logout);
app.get('/authorize', oauth2.authorization);
app.post('/authorize/decision', oauth2.decision);

// set up local server
if (module === require.main) {
    // [START server]
    // Start the server
    var server = app.listen(process.env.PORT || 8080, function () {
        var port = server.address().port;
        console.log('App listening on port %s', port);
    });
    // [END server]
}

module.exports = app;

网站.js:

var passport = require('passport');
var login = require('connect-ensure-login');

// get layout
exports.index = function (req, res) {
  console.log("layout loaded");
  res.render('layout');
}

// get login form
exports.loginForm = function (req, res) {
  console.log("login page loaded");
  res.render('login');
}

// post login form
exports.login = [
  passport.authenticate('local'),
  function (req, res) {
    req.session.save(function (err) {
      res.redirect('/');
    });
  }
]

// logout
exports.logout = function (req, res) {
  req.logout();
  res.redirect('/');
}

Passport 序列化/反序列化用户:

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

passport.deserializeUser(function(id, done) {
  console.log("deserializing user");
  done(null, id);
});

在我的护照身份验证中,为简单起见,我返回了用户 ID,因为这就是我在系统中代表用户所需的全部内容。

标签: node.jsauthenticationredispassport.jspassport-local

解决方案


如果其他人仍然遇到这个问题(比如我),请尝试按照上面 Nathan 的评论并调试您与 redis/mongo/etc 商店的连接。

对我有用的是我将我的 redis 主机设置为,http://localhost所以我将它换成了127.0.0.1(当然是本地开发),一切都立即奏效了。


推荐阅读