I've set up an API to access my backend, and implemented express sessions to authenticate users.
When using Postman to login, and then access protected GET requests, it works fine.
But the React SPA that i'm building can't seem to use the session to authenticate itself, after logging in.
I tried many suggestions i found online (changing CORS headers, using explicit cookie setting in React, changing the way i store my sessions,...) but none seem to solve the issue.
I'll try to include the relevant Code snippets:
Session & CORS middleware:
//Session Middleware
api.use(session({
genid: (req) => {
console.log('Inside session middleware');
console.log(req.sessionID)
return uuid()
},
cookie: {
maxAge: 60000
},
secret:"123",
resave:false,
saveUninitialized:true,
store: new MongoStore({
mongooseConnection:db,
clear_interval: 3600
})
}));
// CORS
api.use(function(req,res,next){
res.header("Access-Control-Allow-Origin", "http://localhost:3000");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Credentials", "true")
next();
})
Login Function & Passport auth:
exports.login = (req,res,next) => {
passport.authenticate('local',(err,user,info) =>{
//... (login handling)
})(req,res,next);
}
// Passport Middleware
passport.use(new LocalStrategy(
(username, password, done) => {
Promotor.findOne({username:username,password:password}, (err,user) =>{
if (err) {
done(err,null);
}
if (!user){
done(null,false,{message:'Invalid Credentials!'})
} else {
done(null,user)
}
});
}
));
// Passport serializing
passport.serializeUser((user,done) => {
done(null,user._id);
});
passport.deserializeUser((id,done) => {
Promotor.findById(id,function(err,user){
if(err){
done(err,false);
} else {
done(null,user);
}
})
})
Protected GET function
(isAuthenticated() Returns false when using axios from my SPA)
exports.getNameById = (req,res) => {
console.log(req.session)
console.log(req._passport)
if(!req.isAuthenticated()){ //RETURNS FALSE IN REACT & TRUE IN POSTMAN
return res.status(401).send();
}
return controller.getDocumentById(Promotor,'firstname lastname',req,res);
}
Axios Request to Log In
(Works in both Postman & app, and correctly creates session)
handleSubmit(e){
console.log("Trying To log in");
axios
.post(`${api_url}/promotor/login`,{username: this.state.username, password:this.state.password})
.then( (res) => {
if (res.status === 200) {
console.log(res);
this.setState(() => ({toClientHome: true, id:res.data.id}));
}
});
e.preventDefault();
}
Axios request to access protected GET request
(GET request works in postman when session cookie is set, but not with axios)
getFullName(id) {
axios
.get(`${api_url}/promotor/name/${id}`,{
withCredentials: true
})
.then((res) => {
//... rest of the code
});
}
Could you please put your cors middleware code on the top of your file(after all imports)!!
api.use(function(req,res,next){
res.header("Access-Control-Allow-Origin", "http://localhost:3000");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Credentials", "true")
next();
})
Then try it again.