首页 > 解决方案 > 使用 express-session 和 connect-session-sequelize 时 this.sessionModel.find 不是函数

问题描述

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

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

我非常害怕我正在使用的软件包有问题。有没有人遇到过这个问题?我将在下面添加一些代码片段,让我知道是否需要提供更多信息,非常感谢您。这是我设置服务器的方式:

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

标签: node.jsauthenticationsessionsequelize.jsexpress-session

解决方案


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

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

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

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

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

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

注意.default模型要求。

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


推荐阅读