Express Sequelize 和 Passport.js 身份验证策略不起作用

Posted

技术标签:

【中文标题】Express Sequelize 和 Passport.js 身份验证策略不起作用【英文标题】:Express Sequelize and Passport.js authentication strategy not working 【发布时间】:2015-11-01 06:49:08 【问题描述】:

我对 Express 和 Sequelize 使用 passport.js 有以下身份验证策略:

var LocalStrategy = require('passport-local').Strategy;
var User = require('../../models').User;

module.exports = function (passport) 

    passport.use('register', new LocalStrategy(
            passReqToCallback: true,
            usernameField: 'email'
        , function (req, email, password, done) 

            //var findOrCreateUser = function () 
            // find a user in Mongo with provided username
            User.findOrCreate(where: email: email).spread(
                function (user, created) 
                    // In case of any error, return using the done method
                    //if (err) 
                    //    console.log('Error in SignUp: ' + err);
                    //    return done(err);
                    //

                    if (email !== req.param('email-confirm')) 
                        console.log('Registration: Email address do not match');
                        return done(null, false, message: 'Email addresses do not match');
                    

                    // already exists
                    if (user) 
                        console.log('User ' + email + ' is already registered.');
                        return done(null, false, 'message': 'The email ' + email + ' is already registered.');
                     else 


                        // if there is no user with that email
                        // create the user
                        var newUser = new User();

                        // set the user's local credentials
                        newUser.email = email;
                        newUser.password = password;

                        // save the user
                        newUser.save(function (err) 
                            if (err) 
                                console.log('Error in Saving user: ' + err);
                                throw err;
                            
                            console.log('New user registration', newUser);
                            return done(null, newUser);
                        );
                    
                );
            //;
            //// Delay the execution of findOrCreateUser and execute the method
            //// in the next tick of the event loop
            //process.nextTick(findOrCreateUser);
        )
    );

;

问题是当我执行代码时,它无法插入到数据库中,并出现以下错误:

Executing (fa4929e4-6b35-40ce-9e02-daf80af507e1): START TRANSACTION;
Executing (fa4929e4-6b35-40ce-9e02-daf80af507e1): SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
Executing (fa4929e4-6b35-40ce-9e02-daf80af507e1): SET autocommit = 1;
Executing (fa4929e4-6b35-40ce-9e02-daf80af507e1): SELECT "id", "email", "password", "lastLogin", "createdAt", "updatedAt", "deletedAt" FROM "Users" AS "User" WHERE ("User"."deletedAt" IS NULL AND "User"."email" = 'user@email.com') LIMIT 1;
Executing (fa4929e4-6b35-40ce-9e02-daf80af507e1): COMMIT;
Unhandled rejection TypeError: Object [object SequelizeInstance:User] has no method 'isModified'
    at sequelize.define.instanceMethods.save (/home/otis/Developer/Project/models/users.js:24:26)
    at Model.create (/home/otis/Developer/Project/node_modules/sequelize/lib/model.js:1735:6)
    at Object.<anonymous> (/home/otis/Developer/Project/node_modules/sequelize/lib/model.js:1837:17)
    at Object.tryCatcher (/home/otis/Developer/Project/node_modules/sequelize/node_modules/bluebird/js/main/util.js:26:23)
    at Promise._settlePromiseFromHandler (/home/otis/Developer/Project/node_modules/sequelize/node_modules/bluebird/js/main/promise.js:503:31)
    at Promise._settlePromiseAt (/home/otis/Developer/Project/node_modules/sequelize/node_modules/bluebird/js/main/promise.js:577:18)
    at Async._drainQueue (/home/otis/Developer/Project/node_modules/sequelize/node_modules/bluebird/js/main/async.js:128:12)
    at Async._drainQueues (/home/otis/Developer/Project/node_modules/sequelize/node_modules/bluebird/js/main/async.js:133:10)
    at Async.drainQueues (/home/otis/Developer/Project/node_modules/sequelize/node_modules/bluebird/js/main/async.js:15:14)
    at process._tickCallback (node.js:415:13)

我知道这是在用户创建期间,因为如果我使用相同的电子邮件地址出错,一切正常。但是如果它开始创建一个用户,它就会出错,并且网页会停止。

更新:如果我只用 .find 运行它:

Executing (default): SELECT "id", "email", "password", "lastLogin", "createdAt", "updatedAt", "deletedAt" FROM "Users" AS "User" WHERE ("User"."deletedAt" IS NULL AND "User"."email" = 'user@email.com') LIMIT 1;
Unhandled rejection TypeError: expecting an array, a promise or a thenable

    See http://goo.gl/s8MMhc

    at PromiseArray.init [as _init] (/home/otis/Developer/Project/node_modules/sequelize/node_modules/bluebird/js/main/promise_array.js:42:27)
    at Promise._settlePromiseAt (/home/otis/Developer/Project/node_modules/sequelize/node_modules/bluebird/js/main/promise.js:575:21)
    at Promise._settlePromises (/home/otis/Developer/Project/node_modules/sequelize/node_modules/bluebird/js/main/promise.js:693:14)
    at Async._drainQueue (/home/otis/Developer/Project/node_modules/sequelize/node_modules/bluebird/js/main/async.js:123:16)
    at Async._drainQueues (/home/otis/Developer/Project/node_modules/sequelize/node_modules/bluebird/js/main/async.js:133:10)
    at Async.drainQueues (/home/otis/Developer/Project/node_modules/sequelize/node_modules/bluebird/js/main/async.js:15:14)
    at process._tickCallback (node.js:415:13)

更新:删除.spread

Executing (default): SELECT "id", "email", "password", "lastLogin", "createdAt", "updatedAt", "deletedAt" FROM "Users" AS "User" WHERE ("User"."deletedAt" IS NULL AND "User"."email" = 'user@email.com') LIMIT 1;
express deprecated req.param(name): Use req.params, req.body, or req.query instead middlewares/authentication/registration-strategy.js:21:39
Unhandled rejection TypeError: object is not a function
    at null.<anonymous> (/home/otis/Developer/Project/middlewares/authentication/registration-strategy.js:35:39)
    at tryCatcher (/home/otis/Developer/Project/node_modules/sequelize/node_modules/bluebird/js/main/util.js:26:23)
    at Promise._settlePromiseFromHandler (/home/otis/Developer/Project/node_modules/sequelize/node_modules/bluebird/js/main/promise.js:503:31)
    at Promise._settlePromiseAt (/home/otis/Developer/Project/node_modules/sequelize/node_modules/bluebird/js/main/promise.js:577:18)
    at Promise._settlePromises (/home/otis/Developer/Project/node_modules/sequelize/node_modules/bluebird/js/main/promise.js:693:14)
    at Async._drainQueue (/home/otis/Developer/Project/node_modules/sequelize/node_modules/bluebird/js/main/async.js:123:16)
    at Async._drainQueues (/home/otis/Developer/Project/node_modules/sequelize/node_modules/bluebird/js/main/async.js:133:10)
    at Async.drainQueues (/home/otis/Developer/Project/node_modules/sequelize/node_modules/bluebird/js/main/async.js:15:14)
    at process._tickCallback (node.js:415:13)

【问题讨论】:

如果将 findOrCreate 替换为 find 会发生什么?由于您稍后创建用户,因此无需使用它。 删除spread:findOne(email: email).then(function(user) ... ) 抱歉什么意思? spread 期望值数组或承诺。但是findOne/find 返回单个值。所以用User.findOne(email: email).then(function(user) ... )替换User.findOne().spread() 【参考方案1】:

sequelize 模型不是构造函数(即不能调用new)。

http://docs.sequelizejs.com/en/latest/api/model/

将其用作工厂,通过调用 build(它返回一个新的、未保存的实例)或调用 create(它返回一个使用已保存实例解析的 Promise)来使用

【讨论】:

以上是关于Express Sequelize 和 Passport.js 身份验证策略不起作用的主要内容,如果未能解决你的问题,请参考以下文章

node+pm2+express+mysql+sequelize来搭建网站和写接口

Node.js / Sequelize.js / Express.js - 如何插入多对多关联? (同步/异步?)

在 Express.js 中停止执行 Sequelize 承诺

nodejs: express sequelize-cli

nodejs: express sequelize-cli

sequelize抛出错误方言需要在express js中显式定义