【问题标题】:this.sessionModel.find is not a function when using express-session and connect-session-sequelize使用 express-session 和 connect-session-sequelize 时 this.sessionModel.find 不是函数
【发布时间】:2020-09-30 05:41:56
【问题描述】:

我刚刚意识到,当我登录该应用程序时,我一直在开发的应用程序不再工作。登录后,我得到一个空白页面,带有

this.sessionModel.find is not a function 打印在顶部,控制台出现 500 错误

我非常害怕我使用的软件包有问题。以前有没有人遇到过这个问题?我将在下面添加一些代码 sn-ps,如果我需要提供更多信息,请告诉我,非常感谢您。这是我设置服务器的方式:

const path = require('path')
const express = require('express')
const morgan = require('morgan')
const bodyParser = require('body-parser')
const compression = require('compression')
const session = require('express-session')
const passport = require('passport')
const SequelizeStore = require('connect-session-sequelize')(session.Store)
const db = require('./db')
const sessionStore = new SequelizeStore({db})
const PORT = process.env.PORT || 8080
const sslRedirect = require('heroku-ssl-redirect')
const app = express()
module.exports = app

/**
this file is where we import middleware, route the routes, sync the db, and start the server.
 */
if (process.env.NODE_ENV !== 'production') require('../secrets')

// passport registration
passport.serializeUser((user, done) => done(null, user.id))
passport.deserializeUser((id, done) =>
  db.models.user.findById(id)
    .then(user => done(null, user))
    .catch(done))

const createApp = () => {
  // logging middleware
  app.use(morgan('dev'))

  // body parsing middleware
  app.use(bodyParser.json())
  app.use(bodyParser.urlencoded({ extended: true }))

  // compression middleware
  app.use(compression())

  // session middleware with passport
  app.use(session({
    secret: process.env.SESSION_SECRET || 'nothing',
    store: sessionStore,
    resave: false,
    saveUninitialized: false
  }))
  app.use(passport.initialize())
  app.use(passport.session())

  // auth and api routes
  app.use(sslRedirect())
  app.use('/auth', require('./auth'))
  app.use('/api', require('./api'))

  // static file-serving middleware
  app.use(express.static(path.join(__dirname, '..', 'public')))

  // any remaining requests with an extension (.js, .css, etc.) send 404
  app.use((req, res, next) => {
    if (path.extname(req.path).length) {
      const err = new Error('Not found')
      err.status = 404
      next(err)
    } else {
      next()
    }
  })


  // sends index.html
  app.use('*', (req, res) => {
    res.sendFile(path.join(__dirname, '..', 'public/index.html'))
  })

  // error handling endware
  app.use((err, req, res, next) => {
    console.error(err)
    console.error(err.stack)
    res.status(err.status || 500).send(err.message || 'Internal server error.')
  })
}

const startListening = () => {
  // start listening (and create a 'server' object representing our server)
  const server = app.listen(PORT, () => console.log(`Serving on port ${PORT}`))
}

const syncDb = () => db.sync()

// This evaluates as true when this file is run directly from the command line,
// i.e. when we say 'node server/index.js' (or 'nodemon server/index.js', or 'nodemon server', etc)
// It will evaluate false when this module is required by another module - for example,
// if we wanted to require our app in a test spec
if (require.main === module) {
  sessionStore.sync()
    .then(syncDb)
    .then(createApp)
    .then(startListening)
} else {
  createApp()
}

这是我的登录路线:

const router = require('express').Router()
const User = require('../db/models/user')
module.exports = router

//routes for login authentication


//login
router.post('/login', (req, res, next) => {
  User.findOne({where: {email: req.body.email}})
    .then(user => {
      if (!user) {
        res.status(401).send('User not found')
      } else if (!user.correctPassword(req.body.password)) {
        res.status(401).send('Incorrect password')
      } else {
        req.login(user, err => (err ? next(err) : res.json(user)))
      }
    })
    .catch(next)
})

//change password
router.put('/:id/resetpw', (req, res, next) => {
  User.update(req.body, {
    where: {
      id: req.params.id
    },
    individualHooks: true
  })
    .then(([updatedRows, [updatedUser]]) => {
      res.status(200).json(updatedUser)
    })
    .catch(next)
})

//sign up
router.post('/signup', (req, res, next) => {
  User.create(req.body)
    .then(user => {
      req.login(user, err => (err ? next(err) : res.json(user)))
    })
    .catch(err => {
      if (err.name === 'SequelizeUniqueConstraintError') {
        res.status(401).send('User already exists')
      } else {
        next(err)
      }
    })
})

//logout
router.post('/logout', (req, res) => {
  req.logout()
  req.session.destroy()
  res.redirect('/')
})

router.get('/me', (req, res) => {
  res.json(req.user)
})

【问题讨论】:

  • 当我将 sequelize 从版本 ^4.3.1 更新到版本 ^5.21.3 时,问题可能已经暴露出来
  • 问题是升级 sequelize,所以我假设 connect-session-sequelize 包不适用于较新的版本

标签: node.js authentication session sequelize.js express-session


【解决方案1】:

这通常表示尝试加载定义为 ES6 导出的模块。

例如,要在 Express 中加载最新版本的 heroku-ssl-redirect(截至目前),必须使用:

const sslRedirect = require('heroku-ssl-redirect').default;

注意最后的.default。您的 heroku-ssl-redirect 导入似乎在没有它的情况下工作,但我今天安装的最新版本需要 .default 否则会引发相同的错误,在这种情况下读取 sslRedirect is not a function

我看不到您的模型的代码,但在this thread 中,使用 Sequelize 时使用相同的方法加载模型:

const model = require(modelPath).default(sequelize, Sequelize);

请注意型号要求处的.default

这可能是您错误的软件包的问题。

【讨论】:

    猜你喜欢
    • 2022-10-02
    • 2016-03-02
    • 1970-01-01
    • 1970-01-01
    • 2017-10-28
    • 1970-01-01
    • 2018-03-07
    • 2019-09-26
    • 2021-06-05
    相关资源
    最近更新 更多