我一直在尝试使用React和Node进行登录。我已经使用axios从前端发送请求,并在后端使用Passport Express。
此代码对Postman完全适用,但对浏览器不适用。我从浏览器发送请求时未定义req.session.passport
,即未调用deserialize()。邮递员不会发生这种情况。
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');
})
使用护照代码表达
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");
});
答案 0 :(得分:0)
我找到了解决方案。原来axios在axios.get('url',{withCrendentials:true})
上遇到了问题。设置withCrendentails:true不适用于此方法。因此每次都会创建新的sessionID,因此req.session.passport
是未定义的。我必须显式设置axios.defaults.withCrendentails
= true,然后一切正常。