【问题标题】:Why does sequelize return 500 [object SequelizeInstance:Users] when connecting to express session?为什么sequelize在连接express session时返回500 [object SequelizeInstance:Users]?
【发布时间】:2018-10-19 09:04:47
【问题描述】:

问题:

我正在尝试使用本地护照策略对用户进行身份验证。我可以成功地从数据库中检索用户,但是当我尝试重定向到“/”并启动一个新会话时,我的服务器响应为 500 [object SequelizeInstance:Users]

上下文:

我遇到了“connect-session-sequelize”节点包,并在我的 app.js 中实现了它:

const db = require('./models/db.js');
const userController = require('./controllers/user');
const myStore = new SequelizeStore({
  db: db.sequelize,
  table: 'Sessions'
});

app.use(cookieParser());
app.use(session({
  secret: process.env.SESSION_SECRET,
  store: myStore,
  resave: false, // per the express-session docs this should be set to false
  proxy: true,
  saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());

app.get('/login', userController.getLogin);
app.post('/login', userController.postLogin);
app.get('/signup', userController.getSignup);
app.post('/signup', userController.postSignup);

db.sequelize.sync({
  force: false,
}).then(() => {
  app.listen(app.get('port'), () => {
    console.log('%s App is running at http://localhost:%d in %s mode', chalk.green('✓'), app.get('port'), app.get('env'));
  });
});

我处理请求的路线:

const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const db = require('../models/db.js');
const User = db.user;

passport.serializeUser((user, done) => {
  console.log('serializing user: ', user);
  done(null, user);
});

passport.deserializeUser((id, done) => {
  User.findById(id).then((user) => {
    done(user);
  });
});

passport.use(new LocalStrategy({ usernameField: 'email' }, (email, password, done) => {
  User.findOne({
    where: { email: email.toLowerCase() },
  }).then((user) => {
    if (!user) {
      return done(null, false, { msg: `Email ${email} not found.` });
    }
    user.comparePassword(password, (err, isMatch) => {
      if (err) { return done(err); }
      if (isMatch) {
        return done(null, user);
      }
      return done(null, false, { msg: 'Invalid email or password.' });
    });
  });
}));

exports.postSignup = (req, res, next) => {
  const errors = req.validationErrors();
  const user = new User({
    username: req.body.name,
    email: req.body.email,
    password: req.body.password
  });

  User.findOne({
    where: { email: req.body.email }
  }).then((existingUser) => {
    if (existingUser) {
      req.flash('errors', { msg: 'Account with that email address already exists.' });
      return res.redirect('/signup');
    }
    user.save((err) => {
      req.logIn(user, (err) => {
        req.session.save(() => res.redirect('/'));
      });
    });
  });
};

“用户”数据库模型:

const bcrypt = require('bcrypt-nodejs');

module.exports = (sequelize, DataTypes) => {
  const Users = sequelize.define('Users', {
    id: {
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4,
      primaryKey: true,
      allowNull: false,
      unique: true
    },
    username: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: true
    },
    email: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: true
    },
    password_hash: {
      type: DataTypes.STRING
    },
    password: {
      type: DataTypes.VIRTUAL,
      allowNull: false,
      unique: false,
      set(value) {
        const that = this;
        bcrypt.genSalt(10, (err, salt) => {
          if (err) { return console.log('BCRYPT GEN SALT ERR:', err); }

          bcrypt.hash(value, salt, null, (error, hash) => {
            if (error) { return console.log('BCRYPT HASH ERR:', err); }

            console.log('--> SEQ: BCRYPT hash SET', hash);
            that.setDataValue('password', value);
            that.setDataValue('password_hash', hash);
          });
        });
      }
    }
  });

  Users.prototype.comparePassword = function comparePassword(candidatePassword, cb) {
    bcrypt.compare(candidatePassword, this.password_hash, (err, isMatch) => {
      cb(err, isMatch);
    });
  };
  return Users;
};

“会话”数据库模型:

module.exports = (sequelize, DataTypes) => sequelize
  .define('Sessions', {
    sid: {
      type: DataTypes.STRING,
      primaryKey: true
    },
    userId: DataTypes.STRING,
    expires: DataTypes.DATE,
    data: DataTypes.STRING(50000),
  });

服务器响应:

POST /login 302 234.474 毫秒 - 46

执行中(默认):SELECT "sid", "userId", "expires", "data", "createdAt", "updatedAt" FROM "Sessions" AS "Sessions" WHERE "Sessions"."sid" = 'Jhmo9YA9MhwKEVa6zWxvvRQGdYoXmdSQ';

正在执行(默认):SELECT "id", "username", "email", "password_hash", "phone", “年龄”、“性别”、“位置”、“createdAt”、“updatedAt” FROM “Users” AS “Users”

WHERE "用户"."id" = 'c40d4cd6-4937-4a66-b785-d302e9fa6c40';

正在执行(默认):UPDATE "Sessions" SET "expires"='2018-05-10 06:31:42.797 +00:00',"updatedAt"='2018-05-09 06:31:42.797 +00:00' 其中“sid”= 'Jhmo9YA9MhwKEVa6zWxvvRQGdYoXmdSQ'

[对象 SequelizeInstance:Users] GET / 500 5.420 毫秒 - -

【问题讨论】:

    标签: node.js express session sequelize.js passport.js


    【解决方案1】:

    deserializeUser 应该首先调用 done 并出现错误:

    passport.serializeUser((user, done) => {
      console.log('serializing user: ', user.id);
      done(null, user.id);
    });
    
    passport.deserializeUser((id, done) => {
      User.findById(id).then((user) => {
        done(null, user);
      }).catch(done);
    });
    

    【讨论】:

    • 就是这样!感谢您的回答,我认为用户反序列化发生在注销而不是登录时?
    • 不,deserializeUser 在服务器收到请求并在会话存储中通过 id 查找用户时发生。 serializeUser 在登录或请求结束时发生,将用户 ID 保存到会话中。
    猜你喜欢
    • 1970-01-01
    • 2014-08-21
    • 2011-07-13
    • 2016-03-02
    • 2019-07-28
    • 2011-05-22
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    相关资源
    最近更新 更多