Reputation: 61
I have been trying to do login using React and Node. I have used axios for sending request from front end and Express with Passport at back end.
This code works perfectly for Postman but doesn't work for browser. req.session.passport
is undefined when I send request from browser ie deserialize() is not called. This doesn't happen with Postman.
axios.get('http://localhost:3001/api/admin/authenticate',{ withCredentials: true})
.then(res=>{
console.log("logged in);
this.getState(); //ignore this function just used to change state
return this.props.history.push('./Lesson_modules_Admin');
})
.catch(err=>{
console.log(err);
return this.props.history.push('./login');
})
Express with Passport code
app.use('/', express.static(__dirname + '/../client'));
app.use(cors({credentials:true, origin:"http://localhost:3000"}));
app.use(logger('dev'));
app.use(busboyBodyParser({ multi : true }));
//app.use(bodyparser());
app.use(bodyparser.urlencoded({ extended: true }));
app.use(express.json());
app.use(cookieparser("password"));
app.use(session({
secret : "password",
resave : false,
saveUninitialized : true ,
cookie: {
path: '/',
httpOnly: true,
secure: false,
maxAge: 1800000
},
name : "id"
}));
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser((user,done)=>{
console.log("inside serial");
//req.session.user=user;
done(null,{_id: user._id,isAdmin: user.isAdmin});
});
// used to deserialize for proving you're logged in
passport.deserializeUser( (user,done) =>{
console.log("inside deserial",user);
User.findById(user._id , (err,user)=>{
done(err,user);
});
});
passport.use('local-login',new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
}, async(req,email,password,done)=>{
//console.log("inside login auth");
const user = await User.findOne({'email': email});
//console.log("inside pass",user);
if (!user) return done(null,false);
else{
const validPassword = await bcrypt.compare(req.body.password,user.password);
//console.log("password",validPassword);
if (!validPassword) return done(null,false);
req.session.user=user;
return done(null,user);
}
}));
//routes
//to check whether user is logged in
router.get('/authenticate',async(req,res) => {
console.log(req.session.passport,req.session,req.sessionID,req.isAuthenticated());
if(req.session.passport != undefined ){
console.log("here",req.session.passport)
console.log(req.session.passport.user.isAdmin,req.sessionID);
//if( req.session.passport.user.isAdmin == false) console.log("false")
//else console.log("true");
if ( (! req.isAuthenticated() ) || (req.session.passport.user.isAdmin == false) ){
console.log("yes")
res.status(403).send(false);
}
else{
//console.log("wtf",req.isAuthenticated());
res.send(true);
}
}
else{
res.status(403).send(false);
}
});
//for login
router.post('/authenticate', async (req,res,next)=>{
//console.log(req.sessionID,req.session.user);
const user = await User.findOne({"email":req.body.email});
if(!user) return res.status(404).send("User not found");
console.log(user.isAdmin,"here is")
if(user.isAdmin){
console.log("inside")
passport.authenticate('local-login', (err,user,d)=>{
if(err) return next(err);
//console.log("user",user,err,d);
if(!user) return res.status(401).send({ success : false, message : 'authentication failed' });
req.login( user , loginerr => {
if(loginerr) return next(loginerr);
return res.status(200).send(user);
});
})(req,res,next);
}
else res.status(403).send("Accesss Denied");
});
Upvotes: 1
Views: 2015
Reputation: 61
I got the solution. Turns out axios had some problem with axios.get('url',{withCrendentials:true})
. Setting withCrendentails : true wasn't working with this method.Hence new sessionID was created each time and so req.session.passport
was undefined. I had to set axios.defaults.withCrendentails
= true explicitly and then it worked all well.
Upvotes: 5