问题
When trying to implement the example code from the passport guide, I'm running into an issue where the most recently logged in user "replaces" all others. For example:
user1 logs in and leaves a note as user1
user2 logs in
now when user1 leaves a note, it's posted as user2
Do the user sessions need to be stored in a database with something like connect-mongo or does passport keep track of individual sessions? It seems like the API calls are always getting the req.user for the most recent user, regardless of which user makes it.
A similar question had a problem with the serializer. I'm not sure where my problem lies so I'll just post it all.
// 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'));
})
回答1:
I can think of several reasons why this might happen:
- when you (mistakenly) create a global variable to hold some form of state information, like your suspicious looking
signedInvariable (you don't seem to be doing that in the posted code though); - using
app.localswhere you meant to be usingres.locals(you're also not doing that, but still worth a mention); - you're logging in as a second user from a different tab/window from the same browser; sessions are shared across tabs/windows, so when you log in as
UserAfrom one tab, and subsequently log in asUserBfrom another, you can't perform actions asUserAanymore before that session was overwritten by theUserBsession; try logging in asUserBfrom a different browser;
来源:https://stackoverflow.com/questions/20139283/node-passport-multiple-users