在nodejs中使用sequelize和passport登录

时间:2018-04-11 09:52:47

标签: javascript node.js sequelize.js passport.js passport-local

我正在使用用户身份验证创建一个自我持续的聊天应用程序项目。以下代码能够成功注册(添加新用户)。但是,不会发生以前注册用户的登录。 示例:输入用户名为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.server.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"))

这里的介绍是公共文件(每个人都可以访问,即主页),而聊天是私人文件(只有登录用户可以访问)

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.passport.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);
        });
    }
));

}

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

1 个答案:

答案 0 :(得分:1)

代码有两个与Login相关的问题。

1. Sequelize Querying与Promises合作。护照本地策略回调中的Sequelize Query试图使用回调而不是Promises。所以,

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.另一个问题是在server.js中,必须在Passport初始化之后调用路由器函数,以在实际尝试使用Passport之前初始化Passport。 否则,登录和其他路由将尝试在护照的初始化中间件之前使用Passport,从而导致错误。所以,

require('./app/routes.js')(app, passport);

后必须移动

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

<小时/> 这两个修复程序应启用用户登录。