Passport.JS:错误:无法将用户反序列化出会话

Eli*_*ias 5 node.js express passport.js express-session

我使用 Passport.JS 与 Express-Session 和 MySQL 数据库来处理用户身份验证。一切都工作正常,直到我从数据库“会话”中删除所有会话以及从数据库“用户”中删除所有用户。从那时起,我不断收到错误:

“无法从会话中反序列化用户”

deserialize() 函数中的 user_id 似乎是一个 bool,这是正确的。在删除用户和会话之前,这是一个允许我从数据库中获取用户的 ID。

这是我的代码:

设置

var express             = require('express'),
    app                 = express(),
    bodyParser          = require('body-parser'),
    mysql               = require('mysql'),
    generator           = require('generate-password'),
    cookieParser        = require('cookie-parser'),
    expressValidator    = require('express-validator'),
    session             = require('express-session'),
    passport            = require('passport'),
    MySQLStore          = require('express-mysql-session')(session),
    LocalStrategy       = require('passport-local').Strategy,
    bcrypt              = require('bcrypt');

const saltRounds = 10;

app.set("view engine", "ejs");
app.use(express.static(__dirname + "/public"));
app.use(bodyParser.urlencoded({extended: true}));
app.use(expressValidator());
app.use(cookieParser());
var options = {
   host     : 'localhost',
   user     : 'eliasal',
   database : "c9",
   password : ""
};

var sessionStore = new MySQLStore(options);

app.use(session({
   secret: 'dfsfjdssdvsdvawdslepsv',
   resave: true,
   store: sessionStore,
   saveUninitialized: true
}));

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

//Start MYSQL database
var connection = mysql.createConnection({
   host     : 'localhost',
   user     : 'eliasal',
   database : "c9",
   password : "",
   multipleStatements: true
});
connection.connect(function(err){
    if(!err) {
        console.log("Database is connected ...");
    } else {
        console.log("Error connecting database ...");
    }
});
Run Code Online (Sandbox Code Playgroud)

登录路线

//login
app.post("/login", passport.authenticate('local', {
    successRedirect: '/',
    failureRedirect: '/login',

}), function(req, res, info){
    res.render('/');
});
Run Code Online (Sandbox Code Playgroud)

序列化、反序列化和本地策略

passport.serializeUser(function(user_id, done){
    console.log(user_id);
    done(null, user_id);
});

passport.deserializeUser(function(user_id, done){
    console.log('USER ID : ' + user_id);
    connection.query('SELECT * FROM users WHERE id = ?', [user_id], function (err, rows){
        console.log('RESULT : ' + rows);
        done(err, rows[0]);
    });
});

//Authenticate users
passport.use(new LocalStrategy(
    function(username, password, done) {
        connection.query('SELECT password, salt FROM users WHERE email = ?', [username], function(err, results, fields){
            //DB error
            if(err) {done(err)};
            
            //no user was found
            if(results.length === 0) {
                done(null, false);
            } else {
                var salt = results[0].salt;
                if(bcrypt.hashSync(password, salt) === results[0].password) {
                    //Success
                    return done(null, true);
                } else {
                    //Wrong password
                    return done(null, false);
                }
            }
        });
    }
));

function isAuthenticated(req, res, next) {
    if (req.isAuthenticated())
        return next();
    res.redirect('/login');
}
Run Code Online (Sandbox Code Playgroud)

用户表

CREATE TABLE `users` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `first_name` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `last_name` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `email` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `password` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
 `salt` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
 `created` datetime NOT NULL,
 `modified` datetime NOT NULL,
 `user_role` varchar(100) NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Run Code Online (Sandbox Code Playgroud)

会话表

CREATE TABLE IF NOT EXISTS `sessions` ( 
`session_id` varchar(128) COLLATE utf8mb4_bin NOT NULL, 
`expires` int(11) unsigned NOT NULL, 
`data` text COLLATE utf8mb4_bin, 
PRIMARY KEY (`session_id`) 
) ENGINE=InnoDB;
Run Code Online (Sandbox Code Playgroud)

Eli*_*ias 4

我找到了解决方案。本地策略在成功时返回此值:

return done(null, true);
Run Code Online (Sandbox Code Playgroud)

什么时候应该返回:

return done(null, results[0].id);
Run Code Online (Sandbox Code Playgroud)