我使用Express,MongoDB和MongoJS以及Passport。我的前端只是另一个领域的vanilla JS。目前,Express正在将用户从前端表单保存到Mongo并返回浏览器正在保存的cookie。但是,当我通过前端的GET请求启动另一条路线时,结果我得到req.user === 'undefined'
和req.isAuthenticated() === false
。 Passport似乎正确运行passport.serializeUser
和passport.deserializeUser
但用户未设置到请求中。我肯定错过了什么?
这是我的代码:
app.use(cookieParser('supernova'));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json(options));
app.use(session({
secret: 'supernova',
resave: false,
saveUninitialized: false,
cookie: {
maxAge: 60*60*1000,
secure: false,
httpOnly: false,
domain: 'localhost'
}
}));
app.use(passport.initialize());
app.use(passport.session());
护照:
passport.use('local', new LocalStrategy(
{passReqToCallback : true},
(req, username, password, done) => {
db.users.findOne({'username': username}, (error, user) => {
if (error) {return done(error);}
if (user) {
log('User already exists');
return done(user);
} else {
crypt.hashPassword(password, ((encryptedPassword) => {
var newUser = new User({username: username, password: encryptedPassword});
db.users.save(newUser, (err, data) => {
if (err) {
log(err);
return done(err)
}
log(data);
return done(null, data);
})
}));
}
})
}
));
passport.serializeUser(function(user, done) {
log('serialize: ' + user._id)
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
log('deserialize: ' + id)
db.users.findOne({_id: mongojs.ObjectId(id)}, (err, user) => {
log(user)
if(err) {
log(err);
return done(err);
}
return done(err, user);
});
});
function loggedIn(req, res, next) {
log('logged in: ' + req.user);
// log(req.session)
if (req.isAuthenticated()) { return next(); }
req.session.error = 'Please sign in!';
}
接头:
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
路线:
app.post('/register', passport.authenticate('local', {session: true}), (req, res) => {
req.session.save(() => {
return res.redirect('/')
})
});
app.use('/api', loggedIn, maps);
从前端进行的初始注册呼叫:
document.getElementById('signup').addEventListener('submit', function (e) {
e.preventDefault();
window.fetch(process.env.DB_API_URI + '/register', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
credentials: 'include',
body: JSON.stringify({
username: document.getElementById('signUpUsername').value,
password: document.getElementById('signUpPassword').value
})
})
Express中的req.user
为空的第二个前端呼叫:
return window.fetch(process.env.DB_API_URI + '/maps/' + mapId, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
},
credentials: 'include'
})
答案 0 :(得分:1)
问题是浏览器发送了两个HTTP请求,一个OPTIONS和一个GET请求。 OPTIONS请求未通过凭据发送,因此未通过身份验证检查。我通过将我的功能更新为以下内容来绕过这个:
function loggedIn(req, res, next) {
log('logged in: ' + req.isAuthenticated());
if (req.isAuthenticated() || req.method === 'OPTIONS') {
return next();
}
req.session.error = 'Please sign in!';
res.status(400).send();
}