快速会话不会注销
Posted
技术标签:
【中文标题】快速会话不会注销【英文标题】:express-session won't log out 【发布时间】:2014-12-21 18:51:06 【问题描述】:代码
app.js:
var express = require('express');
var session = require('express-session');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongoStore = require('connect-mongo')(session);
var mongoose = require('mongoose');
var passport = require('passport');
var config = require('./config');
var routes = require('./routes');
var mongodb = mongoose.connect(config.mongodb);
var app = express();
// view engine setup
app.set('views', config.root + '/views');
app.set('view engine', 'jade');
app.engine('html', require('ejs').renderFile);
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded(
extended: false
));
app.use(cookieParser());
app.use(express.static(config.root + '/public'));
app.use(session(
name: 'myCookie',
secret: 'tehSecret',
resave: true,
saveUninitialized: true,
unset: 'destroy',
store: new mongoStore(
db: mongodb.connection.db,
collection: 'sessions'
)
));
app.use(passport.initialize());
app.use(passport.session());
app.use('/', routes);
app.set('port', config.port);
var server = app.listen(app.get('port'), function()
if (config.debug)
debug('Express server listening on port ' + server.address().port);
);
routes.js:
var express = require('express');
var router = express.Router();
var config = require('../config');
var userController = require('../controllers/user');
var authController = require('../controllers/auth');
router.get('/', function(req, res)
res.render('index',
title: config.app.name
);
);
router.route('/users')
.post(userController.postUsers)
.get(authController.isAuthenticated, userController.getUsers);
router.get('/signout', userController.signout);
module.exports = router;
模型/user.js:
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
var UserSchema = new mongoose.Schema(
username:
type: String,
unique: true,
required: true
,
password:
type: String,
required: true
);
// Execute before each user.save() call
UserSchema.pre('save', function(callback)
var user = this;
// Break out if the password hasn't changed
if (!user.isModified('password')) return callback();
// Password changed so we need to hash it
bcrypt.genSalt(5, function(err, salt)
if (err) return callback(err);
bcrypt.hash(user.password, salt, null, function(err, hash)
if (err) return callback(err);
user.password = hash;
callback();
);
);
);
UserSchema.methods.verifyPassword = function(password, cb)
bcrypt.compare(password, this.password, function(err, isMatch)
if (err) return cb(err);
cb(null, isMatch);
);
;
// Export the Mongoose model
module.exports = mongoose.model('User', UserSchema);
控制器/user.js:
var config = require('../config');
var User = require('../models/user');
exports.postUsers = function(req, res)
if (config.debug)
console.log("user.postUsers()");
var user = new User(
username: req.body.username,
password: req.body.password
);
user.save(function(err)
if (err)
return res.send(err);
if (config.debug)
console.log("saved");
res.json(
message: 'New user created!'
);
);
;
exports.getUsers = function(req, res)
if (config.debug)
console.log("user.getUsers()");
User.find(function(err, users)
if (err)
return res.send(err);
if (config.debug)
console.log("users", users);
res.json(users);
);
;
exports.signout = function(req, res)
if (config.debug)
console.log("user.signout()");
res.clearCookie('myCookie');
req.session.destroy(function(err)
req.logout();
res.redirect('/');
);
;
控制器/auth.js:
var passport = require('passport');
var BasicStrategy = require('passport-http').BasicStrategy;
var config = require('../config');
var User = require('../models/user');
passport.serializeUser(function(user, done)
done(null, user.id);
);
passport.deserializeUser(function(id, done)
User.findById(id, function(err, user)
done(err, user);
);
);
passport.use(new BasicStrategy(
function(username, password, done)
User.findOne(
username: username
, function(err, user)
if (err)
return done(err);
// No user found with that username
if (!user)
return done(null, false);
// Make sure the password is correct
user.verifyPassword(password, function(err, isMatch)
if (err)
return done(err);
// Password did not match
if (!isMatch)
return done(null, false);
// Success
return done(null, user);
);
);
));
exports.isAuthenticated = passport.authenticate('basic',
session: false
);
问题
/signout 路由不会结束当前会话。在 req.session.destroy
回调中,req.session
是 undefined
,但对 /users 的新 GET 请求就像会话有效一样。
有人可以帮忙解决这个问题吗?
【问题讨论】:
不登录也能访问 /users 吗? @JasonNichols 不。基本身份验证被触发。但是,一旦我登录,我就无法退出。 您能在您的路线中使用 console.log(req.user) 吗?顺便说一句。 afaik 在您的序列化用户中它实际上应该是 user._id,因为 mongodb 默认使用 _id 而不是 id。 我认为你不能轻易注销基本身份验证,请参阅***.com/questions/233507/… @cschaefflerreq.user
未定义。我还添加了authController.isAuthenticated
到 /signout 路由,现在req.user
是当前登录的用户对象。但是,不会执行注销。
【参考方案1】:
如果像我一样,您是因为问题标题而不是详细信息而来到这里的 - 答案是 req.session.destroy()。我认为注销功能是 passport.js 特有的,如果您使用标准 express-session,它将无法工作。
【讨论】:
【参考方案2】:解决方案
控制器/user.js:
exports.signout = function(req, res)
if (config.debug)
console.log("user.signout()");
req.logout();
res.send(401);
;
顺便说一句。不要介意注销后会话仍在数据库中。 Mongod 在 60 秒后检查并清除它们。
【讨论】:
【参考方案3】:在不使用 req.session.destroy()
的情况下登录 api 尝试 req.logout();
。我希望它会起作用。
【讨论】:
对不起,这也没有用。 (这是我在尝试destroy
之前的第一种方法)。以上是关于快速会话不会注销的主要内容,如果未能解决你的问题,请参考以下文章