快递会议不会退出

时间:2014-10-26 12:59:16

标签: node.js express mongoose passport.js

代码

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 route不会结束当前会话。在req.session.destroy回调中,req.sessionundefined,但对/ users的新GET请求就像会话一样有效。

有人可以帮助解决这个问题吗?

3 个答案:

答案 0 :(得分:4)

如果像我一样,您是因为问题标题而不是全部详细信息而来这里的,答案是req.session.destroy()。我认为注销功能特定于passport.js,如果您使用标准的快速会话,它将无法正常工作。

答案 1 :(得分:3)

解决方案

控制器/ user.js的:

exports.signout = function(req, res) {
  if (config.debug)
    console.log("user.signout()");

  req.logout();
  res.send(401);
};

顺便说一下。注销后不要立即将会话保持在DB中。 Mongod会在60秒后检查并清除它们。

答案 2 :(得分:0)

在不使用req.session.destroy()尝试req.logout();的情况下退出api。我希望它能奏效。