Войти, используя sequelize и паспорт в nodejs

Я создаю проект автономного чат-приложения с аутентификацией пользователя. Следующий код может успешно зарегистрироваться (добавить новых пользователей), однако вход в систему для ранее зарегистрированных пользователей не происходит. Пример: при вводе имени пользователя как 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. Спасибо заранее.

0
0
5 838
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В коде есть две проблемы, связанные с входом в систему.

1. Sequelize Querying работает с обещаниями. Запрос Sequelize в обратном вызове Local Strategy в паспорте пытается использовать обратные вызовы вместо обещаний. Так,

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. Another problem is in server.js, the router functions must be called after the Passport's initialization to initialize the Passport before actually trying to use them. Otherwise, the login and other routes would try to use Passport before passport's initialization middlewares, causing errors. So,
require('./app/routes.js')(app, passport);

должен быть перемещен после

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


These two fixes should enable the User Login.

Другие вопросы по теме