【问题标题】:Node + Passport - multiple usersNode + Passport - 多个用户
【发布时间】:2013-12-07 00:05:51
【问题描述】:

在尝试实现护照指南中的示例代码时,我遇到了一个问题,即最近登录的用户“替换”了所有其他用户。例如:

user1 以 user1 身份登录并留下备注
user2 登录
现在当 user1 留下一个便条时,它会以 user2 的身份发布

用户会话是否需要使用 connect-mongo 之类的数据库存储在数据库中,或者护照是否会跟踪单个会话?似乎 API 调用总是获取最新用户的 req.user,无论是哪个用户创建的。

类似的问题是序列化程序有问题。我不确定我的问题出在哪里,所以我将全部发布。

// Express setup
var http = require('http');
var express = require('express');
var app = express();
var signedIn = false;


// Mongoose setup
var mongoose = require('mongoose');
mongoose.connect('');

var UserSchema = mongoose.Schema({
    username: String,
    password: String
});

var NoteSchema = mongoose.Schema({
    text: String,
    user: String
});

// Used for password authorization
UserSchema.methods.validPassword = function (pwd) {
    return (this.password === pwd);
};

var Users = mongoose.model('Users', UserSchema);
var Notes = mongoose.model('Notes', NoteSchema);


// Passport setup
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;


// Passport Serialize
passport.serializeUser(function (user, done) {
    done (null, user.id);
});

passport.deserializeUser(function (id, done) {
    Users.findById(id, function (err, user) {
        done (err, user);
    });
});

// Use Local Strategy
passport.use(new LocalStrategy(
    function(username, password, done) {
        Users.findOne({ username: username }, function (err, user) {
            if (err) { 
                return done(err); }
            if (!user) {
                return done(null, false, {message: 'Incorrect username' });
            }
            if (!user.validPassword(password)) {
                return done(null, false, { message: 'Incorrect password' });
            }
            console.log(user.username + " is signed in");
            return done(null, user);
        });
        }
    ));

// App configuration

app.configure(function () {

    app.set('port', process.env.PORT || 5000);
    app.set('views', __dirname + '/views');
    app.set('view engine', 'jade');

    app.use(express.static(__dirname + '/public'));

    app.use(express.cookieParser());
    app.use(express.bodyParser());
    app.use(express.methodOverride());

    app.use(express.session({ secret: 'keyboard cat' }));
    app.use(passport.initialize());
    app.use(passport.session());
    app.use(app.router);
})


// Passport Authentication
app.post('/login',
  passport.authenticate('local', { successRedirect: '/notes',
                                   failureRedirect: '/login',
                                   /*failureFlash: true*/ })
);

// API
// Notes
app.get('/api/notes', function (req, res) {
    Notes.find({}, function (err, note) {
        if (err) {
            res.send(err);
        }

        res.json(note);
    })
})

app.post('/api/notes', function (req, res) {
    Notes.create({
        text : req.body.text,
        user : req.user.username,
        done : false

    }, function (err, note) {
        if (err) {
            res.send(err);
        }

        Notes.find(function (err, note) {
            if (err) {
                res.send(err);
            }

            res.json(note);
        })
    })
})

app.delete('/api/notes/:note_id', function (req, res) {
    Notes.remove({ _id : req.params.note_id },
        function (err, req) {
            if (err) {
                res.send(err);
            }

        Notes.find(function (err, note) {
            if (err) {
                res.send(err);
            }

            res.json(note);
        });
    });
});

// Users
// Create New User
app.post('/api/users', function (req, res, next) {
    Users.create({
        username : req.body.username,
        password : req.body.password,
        done : false
    }, function (err, user) {
        if (err) {
            res.send(err);
        } else {
            res.redirect('/login');
        }
    });
});


// Routes

app.get('/', function (req, res) {
    res.render('login');
});

app.get('/login', function (req, res) {
    res.render('login');
})

app.get('/newuser', function (req, res) {
    res.render('newuser');
})

app.get('/notes', function (req, res) {
    if (req.user != null) {
        console.log(req.user);
        res.render('index',  { 'userName' : req.user.username });
    } else {
        res.send("Not signed in!")
    }
});

// HTTP Server

http.createServer(app).listen(app.get('port'), function() {
    console.log("Express server listening on: " + app.get('port'));
})

【问题讨论】:

    标签: node.js passport.js


    【解决方案1】:

    我能想到可能发生这种情况的几个原因:

    • 当您(错误地)创建一个全局变量来保存某种形式的状态信息时,例如看起来可疑的 signedIn 变量(尽管您在发布的代码中似乎没有这样做);
    • 使用app.locals,而你本来打算使用res.locals(你也没有这样做,但仍然值得一提);
    • 您正在作为第二个用户从同一浏览器的不同选项卡/窗口登录;会话在选项卡/窗口之间共享,因此当您从一个选项卡以UserA 登录,然后从另一个选项卡以UserB 登录时,在该会话被UserB 会话;尝试从其他浏览器以UserB 身份登录;

    【讨论】:

    • 我花了太长时间没有尝试不同的浏览器(而不是两个选项卡)。就是这样! :D
    • 可能方便提一下,除非我弄错了,如果您使用的是 chrome,您可以使用多个隐身窗口来隔离会话。
    • @NickMitchinson 我试过了,似乎会话在不同的隐身窗口以及标签之间共享:(
    猜你喜欢
    • 2019-04-17
    • 1970-01-01
    • 2017-12-14
    • 2016-07-04
    • 1970-01-01
    • 2020-02-06
    • 2019-07-23
    • 2020-01-14
    • 2021-12-04
    相关资源
    最近更新 更多