node.js - 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,因为这就是我在系统中代表用户所需的全部内容。
解决方案
如果其他人仍然遇到这个问题(比如我),请尝试按照上面 Nathan 的评论并调试您与 redis/mongo/etc 商店的连接。
对我有用的是我将我的 redis 主机设置为,http://localhost
所以我将它换成了127.0.0.1
(当然是本地开发),一切都立即奏效了。
推荐阅读
- azure-cosmosdb - 在 Azure CosmosDb PatchItemAsync 中获取“指定的输入之一无效”
- javascript - 如何使标题出现在css中div框的顶部
- python - 搜索时使用 pytube 进行线程化
- mod-rewrite - AEM:资产的 URL 缩短
- javascript - 将书签存储在 chrome 根文件夹之外?
- amazon-web-services - AWS Sam delpoy 失败
- node.js - 服务器选择在 30000 毫秒后超时堆栈:MongooseServerSelectionError:服务器选择在 30000 毫秒后超时
- python - 使用python在kivy上打开相机on_pressed
- entity-framework - 如何在 EF 存储库模式中使用 2 个表达式
- jsonpath - 使用 JSONPath 将过滤器应用于对象内的实体