Почему sequelize возвращает 500 [объект SequelizeInstance: Users] при подключении к экспресс-сеансу? - PullRequest
0 голосов
/ 09 мая 2018

Проблема:

Я пытаюсь аутентифицировать пользователя с использованием стратегии passport-local. Я могу успешно извлечь пользователя из базы данных, но когда я пытаюсь перенаправить на «/» и начать новый сеанс, мой сервер отвечает 500 [объект 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 / логин 302 234,474 мс - 46

Выполнение (по умолчанию): ВЫБЕРИТЕ «sid», «userId», «expires», «data», «creationAt», "updatedAt" ИЗ "Сессий" AS "Сеансы" ГДЕ "Сеансы". "sid" = 'Jhmo9YA9MhwKEVa6zWxvvRQGdYoXmdSQ';

Выполнение (по умолчанию): ВЫБЕРИТЕ «id», «username», «email», «password_hash», «phone», "возраст", "пол", "местоположение", "созданный", "обновленный" от "пользователей" как "пользователи"

ГДЕ "Пользователи". "Id" = 'c40d4cd6-4937-4a66-b785-d302e9fa6c40';

Выполнение (по умолчанию): UPDATE "Сеансы" SET "expires" = '2018-05-10 06: 31: 42.797 +00: 00 ', "updatedAt" =' 2018-05-09 06: 31: 42.797 +00: 00 'ГДЕ "sid" = 'Jhmo9YA9MhwKEVa6zWxvvRQGdYoXmdSQ'

[объект SequelizeInstance: пользователи] GET / 500 5,420 мс - -

1 Ответ

0 голосов
/ 09 мая 2018

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);
});
...