【问题标题】:Ssequelizejs, MySQL and passportjs user.findOne not a functionSsequelizejs、MySQL 和 passportjs user.findOne 不是函数
【发布时间】:2023-03-19 11:39:01
【问题描述】:

我目前正在我的 Node js 应用程序中从 mongodb 迁移到 MySQL。我使用 sequelize 作为 ORM,但是在迁移一些 passportjs 代码时遇到了一些问题。

我有以下模态。

user.js:

"use strict";

module.exports = function(sequelize, DataTypes) {
  var User = sequelize.define("users", {
    username: DataTypes.STRING,
    localemail: DataTypes.STRING,
    localpassword: DataTypes.STRING,
    facebookid: DataTypes.STRING,
    facebooktoken: DataTypes.STRING,
    facebookemail: DataTypes.STRING,
    facebookname: DataTypes.STRING,
    twitterid: DataTypes.STRING,
    twittertoken: DataTypes.STRING,
    twitterdisplayname: DataTypes.STRING,
    twitterusername: DataTypes.STRING,
    googleid: DataTypes.STRING,
    googletoken: DataTypes.STRING,
    googleemail: DataTypes.STRING,
    googlename: DataTypes.STRING
  });

  return User;
};

在我的 passportjs 文件中有以下函数:

...

// load all the things we need
var LocalStrategy    = require('passport-local').Strategy;
var FacebookStrategy = require('passport-facebook').Strategy;
var TwitterStrategy  = require('passport-twitter').Strategy;
var GoogleStrategy   = require('passport-google-oauth').OAuth2Strategy;

// load up the user model
var User       = require('../models/user');

...

passport.use('local-login', new LocalStrategy({
        usernameField : 'email',
        passwordField : 'password',
        passReqToCallback : true 
    },
    function(req, email, password, done) {
        if (email)
            email = email.toLowerCase(); 
    // asynchronous
    process.nextTick(function() {
        User.findOne({
            where: {
                localemail: email
            }
        }).then(function(user) {
            // if there are any errors, return the error
            if (err)
                return done(err);

            // if no user is found, return the message
            if (!user)
                return done(null, false, req.flash('loginMessage', 'No user found.'));

            if (!validPassword(password))
                return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.'));

            // all is well, return user
            else
                return done(null, user);
        });
    });

}));

...

应用程序退出并出现以下错误:

passport.js:100
                    User.findOne({
                         ^

TypeError: User.findOne is not a function

我在 github 上查看了这段代码以获得灵感:

https://github.com/sequelize/express-example

对我忽略的内容有什么想法吗?

更新:

所以在我的 passport.js 文件中我已经这样做了:

var models = require('../models'); 
console.log("models.User:" +models.User); 

输出这个:

npm start app.js 
> myapp0.0.0 start /home/mathias/nodejs/myapp 
> DEBUG=express-sequelize 
node ./bin/www "app.js" 
models.User:undefined 
express-sequelize 
Express server listening on port 3000 +0ms express-sequelize 
Listening on port 3000 +7ms –

这会在控制台中给出一个 [object:object]:

var models  = require('../models');
console.log("models:" +models);

这也给出了一个未定义的:

var models  = require('../models').User;
console.log("models:" +models);

使用 config.json 文件更新:

{
  "development": {
    "username": "root",
    "password": "password",
    "database": "myapp",
    "host": "0.0.0.0",
    "dialect": "mysql"
  },
  "test": {
    "username": "root",
    "password": "password",
    "database": "myapp",
    "host": "0.0.0.0",
    "dialect": "mysql"
  },
  "production": {
    "username": "root",
    "password": "password",
    "database": "myapp",
    "host": "0.0.0.0",
    "dialect": "mysql"
  }
}

【问题讨论】:

  • user.js 导出一个返回模型的函数,因此在导入该函数后,您需要调用它(使用正确的参数),返回值将是 User 模型。
  • 嗨 robertklep 我试过用 var models = require('../models').User;没有运气。我可能忽略了什么?

标签: mysql node.js passport.js sequelize.js


【解决方案1】:

问题在于您如何需要该模块。替换:

var User = require('../models/user');

有了这个:

var User = require('../models').User;

之所以这样,是因为模型是动态导出的。你可以看看你的文件,models/index.js。在那里,您会发现每个模型是如何导出到单个对象中的。所以你基本上总是需要 models/index.js 并在那里指定你想要访问的键,在这种情况下是“用户”

【讨论】:

  • 它似乎不起作用(我遇到同样的错误),你是说......“所以你基本上总是需要模型/index.js”......这是意味着我需要 require('../models/index.js');?如果是这样,我应该怎么称呼这个变量(我想其他一些代码应该可以引用它)?
  • 如果你不指定一个键,你可以称之为“模型”。如果您以我回答的方式指定密钥,则将其称为用户或其他名称。给我看一个包含你的 models/index.js 内容的 pastebin
  • 我也试过这个://加载用户模型 var models = require('../models');然后 "models.User.findOne({"
  • 文件路径可能有问题。您确定 ../models 是正确的路径吗?此外,调试 var 模型(或用户)并查看它的输出
  • 当我将文件路径更改为我现在不正确的东西时,例如。 /models 我在开始时收到一个错误,说找不到模块,所以我怀疑路径是否正确?来自 user.js 的 console.log 似乎没有输出有用的东西。
【解决方案2】:

使用对象解构会更好

var { User } = require('../models');

【讨论】:

    【解决方案3】:

    文件user.js 导出一个返回模型的函数:

    module.exports = function(sequelize, DataTypes) {
      ...
      return User;
    }
    

    因此,为了获得该模型参考,您需要使用以下内容:

    const Sequelize = require('sequelize');
    const DataTypes = sequelize.DataTypes;
    
    let sequelize = new Sequelize(...);
    
    const User = require('../models/user')(sequelize, DataTypes);
    

    但是,我不明白您为什么要传递 sequelizeDataTypes,因为您可以轻松地将它们导入模型文件(反过来,可以导出直接建模):

    // models/user.js
    const sequelize = require('sequelize');
    const DataTypes = sequelize.DataTypes;
    
    module.exports = sequelize.define("users", { ... });
    

    使用方法:

    const User = require('../models/user'); 
    

    【讨论】:

    • 所以为了尽量减少对我的代码的影响,我从第一个示例开始,其中 iam 传递 sequelize 和 DataTypes。当这可行时,我将实现您描述的更简单的模型,这更有意义。所以 user.js 看起来仍然像我上面原始问题中的那个。实施您对我的 passport.js 文件描述的更改会在控制台中出现以下错误:/home/tony/code/myapp/models/user.js:4 var User = sequelize.define("users", { ^ TypeError : sequelize.define 不是函数
    • @Tony 哦,我想我误解了代码,sequelize 不是模块引用而是数据库实例(所以是new Sequelize(...) 的结果)。在这种情况下,您可能仍然需要传递它。我会更新我的答案。
    • 非常感谢您的帮助!现在代码编译了。不幸的是,我在尝试使用登录路由时收到一个错误:未处理的拒绝 SequelizeAccessDeniedError: ER_ACCESS_DENIED_ERROR: Access denied for user ''@'localhost' (using password: NO) 我想这可能是因为我的 config.json 文件,我已将其添加到原始问题中。
    • @Tony 根据 MySQL,您没有传递正确的凭据。
    • 但我想知道它是否看到密码/配置,因为“使用密码:否”。我至少会期望一个是和一个用户名?
    猜你喜欢
    • 2020-08-10
    • 2019-04-06
    • 2020-07-24
    • 2018-07-21
    • 1970-01-01
    • 2021-06-02
    • 2019-07-12
    • 2018-09-26
    • 2021-07-14
    相关资源
    最近更新 更多