代码之家  ›  专栏  ›  技术社区  ›  Abhinav Jha

在nodejs中使用sequelize和passport登录

  •  0
  • Abhinav Jha  · 技术社区  · 7 年前

    我正在创建一个具有用户身份验证的自我维持聊天应用程序项目。以下代码能够成功注册(添加新用户)。但是,以前注册的用户不会登录。 示例:在输入用户名为foo和密码为foopass时,这就是终端内部发生的情况

     Executing (default): CREATE TABLE IF NOT EXISTS `users` (`id` INTEGER auto_increment , `email` VARCHAR(255) NOT NULL DEFAULT 'abhinav@gmail.com' UNIQUE, `username` VARCHAR(255) NOT NULL UNIQUE, `password` VARCHAR(255) NOT NULL, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
    Executing (default): SHOW INDEX FROM `users`
    Database is ready
    Executing (default): SELECT `id`, `email`, `username`, `password`, `createdAt`, `updatedAt` FROM `users` AS `users` WHERE `users`.`username` = 'foo' LIMIT 1;
    

    以下是我的js文件

    1.服务器。js公司

    const express = require('express')
    const session = require('express-session')
    const passport = require('passport')
    const path = require('path')
    const http = require('http')
    
    const app = express()
    const server = http.createServer(app)
    const cookieparser = require('cookie-parser')
    const bodyParser   = require('body-parser');
    app.set('views',path.join(__dirname , 'chat'));
    
    app.set('view engine','html');
    var port = process.env.PORT || 5898;
    app.use('/', express.static(path.join(__dirname, 'intro')));
    app.use('/profile', express.static(path.join(__dirname, 'chat')));
    require('./passport')(passport);
    require('./app/routes.js')(app, passport);
    app.use(express.json());
    app.use(session({
        secret: 'project-session',
        resave: true,
        saveUninitialized:true
    }))
    
    app.use(passport.initialize())
    app.use(passport.session())
    
    server.listen(port, () => console.log("Server running on http://localhost:5898"))
    

    这里的intro是公共文件(每个人都可以访问,如主页),而chat是私有文件(仅登录用户可以访问)

    2.app/routes。js公司

    const express = require('express')
    const app = express();
    const route = express.Router()
    const path = require('path');
    const bodyParser = require('body-parser');
    const passport = require('passport-local');
    const Users = require('../db').Users;
    module.exports = function(app,passport)
    {
    
    app.use((bodyParser.urlencoded({ extended: false })))
    app.use(bodyParser.json());
     app.get('/signup', function(req,res) {
         res.render('../intro/index');
     }) 
     app.get('/login',function(req,res){
         res.send({
             username: req.body.username
         })
     }) 
    
    app.post('/signup', function(req,res){
        var a = [req.body.email,req.body.username,req.body.password];
        Users.findOne({
           where: { email: a[0],
            username: a[1],
            password: a[2],
           }
    
        }).then(users => {
            if (users) {
            res.send({
                url:'/'
            })
            }
            else{
                Users.create({
                    email: a[0],
                    username: a[1],
                    password: a[2],
    
              }).then(users => {
                    res.send({
                        url:'/profile',
                        username: a[1]
                    })
              })    
            }
        })
    
    
    })
    app.post('/login', passport.authenticate('local'),
    function(req, res) {
        res.send({
            url:'/profile',
            username:req.body.username
        });
      });
    
    app.get('/logout', function(req, res){
        req.logout();
        res.redirect('/');
      });
    }
    

    3.db。js(使用mysql)

    const Sequelize = require('sequelize');
    
    const db = new Sequelize(
        'socializedb',
        'soc',
        'socpass',
    
        {
            dialect: 'mysql',
            host: 'localhost',
            operatorsAliases: false,
        }
    );
    
    const Users = db.define('users', {
        id: {
            type: Sequelize.INTEGER,
            autoIncrement: true,
            primaryKey: true,
        },
        email: {
            type: Sequelize.STRING,
            allowNull: false,
            unique: true,
            defaultValue: "abhinav@gmail.com"
        },
        username: {
            type: Sequelize.STRING,
            allowNull: false,
            unique: true,
        },
        password: {
            type: Sequelize.STRING,
            allowNull: false,
        }
    
    })
    
    
    db.sync().then(() => console.log("Database is ready"))
    
    exports = module.exports = {
        db,
        Users
    }
    

    4.护照。js(我的本地策略所在地)

    const LocalStrategy = require('passport-local').Strategy
    const Users = require('./db').Users
    module.exports = function(passport)
    {
        console.log("passport is working");
    passport.serializeUser(function (users, done) {
        return done(null, users.id);
        console.log("Serialize");
    
    })
    
    passport.deserializeUser(function (id, done) {
        console.log("DeSerialize");
        Users.findById(id).then((users) => {
            console.log(users);
            return done(null, users);
        });
    })
    
    passport.use(new LocalStrategy(
        function(username, password, done) {
          Users.findOne({where:{ username: username} },
            function(err, users) {
                if (err) { return done(err); }
                if (!users) {
                return done(null, false, { message: 'Incorrect username.' });
                }
                if (!users.password === password) {
                return done(null, false, { message: 'Incorrect password.' });
                }
                return done(null, users);
            });
        }
    ));
    
    }
    

    我使用了本地身份验证。我确信我的数据库没有问题,因为我可以看到驻留在我机器上的表中的条目。我主要认为问题可能是在passport中使用序列化/反序列化。js。提前谢谢。

    1 回复  |  直到 7 年前
        1
  •  4
  •   Anuj Aggarwal    7 年前

    该代码有两个与登录相关的问题。

    1、Sequelize查询与Promises一起工作。passport的本地策略回调中的Sequelize查询试图使用回调而不是承诺。所以

    passport.use(new LocalStrategy(
        function(username, password, done) {
          Users.findOne({where:{ username: username} },
            function(err, users) {
                if (err) { return done(err); }
                if (!users) {
                    return done(null, false, { message: 'Incorrect username.' });
                }
                if (!users.password === password) {
                    return done(null, false, { message: 'Incorrect password.' });
                }
                return done(null, users);
            });
        }
    ));
    

    必须更改为

    passport.use(new LocalStrategy(
        function (username, password, done) {
            Users.findOne({ where: { username: username } })
                 .then(function (users) {
                     if (!users) {
                         return done(null, false, { message: 'Incorrect username.' });
                     }
                     if (!users.password === password) {
                         return done(null, false, { message: 'Incorrect password.' });
                     }
                     return done(null, users);
                 })
                 .catch(err => done(err));
        }
    ));
    

    这有望解决当前的错误。


    2、服务器中存在另一个问题。js中,必须在Passport初始化之后调用路由器函数来初始化Passport,然后才能实际尝试使用它们。 否则,登录和其他路由将尝试在Passport的初始化中间件之前使用Passport,从而导致错误。所以
    require('./app/routes.js')(app, passport);
    

    必须在之后移动

    app.use(passport.initialize())
    app.use(passport.session())
    


    这两个修复程序应允许用户登录。