NodeJS 和 Passport:用户是随机变化的

NodeJS and Passport: user is randomly changing

我已将 nodejs 通行证登录添加到我的应用程序并且一切正常,直到我将更改提交到生产环境。这个问题非常有线:当我重新加载页面时,用户有时会随机更改。

这是我的 app.js 代码:

var mysql = require('promise-mysql');  
var passport = require('passport');
var app = express();

app.use(cookieParser()) 
app.use(session({
    secret: 'keyboard cat',
    maxAge: 60 * 5,
    resave: false,
    saveUninitialized: false
}))
app.use(passport.initialize());
app.use(passport.session());


mysql.createConnection(dbConfig.connection).then(
    function (connection) {
        require('./config/passport')(passport, connection); // pass passport for configuration
    }
);

这是我在 configs/passport.js

中的内容
var LocalStrategy = require('passport-local').Strategy;
var bcrypt = require('bcrypt-nodejs');
module.exports = function (passport, connection) {
    passport.serializeUser(function (user, done) {
        done(null, user.name);
    });

    // used to deserialize the user
    passport.deserializeUser(function (name, done) {
        connection.query("SELECT * FROM users WHERE name = ? ", [name])
            .then(function (rows) {
                done(null, rows[0]);
            })
            .catch(function (err) {
                console.log("Error getting user form DB: ", err);
                done(err);
            });
    });

passport.use(
        'local-login',
        new LocalStrategy({
                usernameField: 'username',
                passwordField: 'password',
                passReqToCallback: true // allows us to pass back the entire request to the callback
            },
            function (req, username, password, done) { // callback with email and password from our form
                connection.query("SELECT * FROM users WHERE username = ?", [username])
                    .then(function (rows) {
                        if (!rows.length) {
                            done(null, false); // req.flash is the way to set flashdata using connect-flash
                        }

                        // if the user is found but the password is wrong
                        else if (!bcrypt.compareSync(password, rows[0].password)) {
                            done(null, false); // create the loginMessage and save it to session as flashdata
                            // all is well, return successful user
                        }
                        else {
                            done(null, rows[0]);
                        }

                    })
                    .catch(function (err) {
                        console.log("Login Failed: ", err.body);
                        done(err);
                    });
            })
    );
};

这就是我在每个路由文件中的内容:

router.all('*', function (req, res, next) {
    if (req.isAuthenticated()) {
        user.init(req.user);
        next(); // pass control to the next handler
    }
    else {
        res.redirect('/');
    }
});

有没有人遇到过类似的问题?好像我犯了一些简单而愚蠢的错误,因为 google 找不到类似的问题。

谢谢!

您正在执行两个不同的查询:

// passport.deserializeUser()
connection.query("SELECT * FROM users WHERE name = ? ", [name])

// In the Passport verification handler
connection.query("SELECT * FROM users WHERE username = ?", [username])

我的猜测是 name 不是唯一的,您希望在任何地方都使用 username

顺便说一句:您将 maxAge 设置为 300 毫秒

事实证明是节点js在内存中存储对象的问题。我不完全明白这是怎么发生的,但这是我发现的。

我将 req.user 存储在 userModel 对象中,如果服务器上有很多请求,这个 userModel 对象有时会与来自不同用户的数据混淆。

解决方案是到处直接用户 req.user。