Passport会话适用于Postman,但不适用于浏览器

时间:2019-03-19 18:30:17

标签: node.js reactjs express axios passport.js

我一直在尝试使用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");

    });

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。原来axios在axios.get('url',{withCrendentials:true})上遇到了问题。设置withCrendentails:true不适用于此方法。因此每次都会创建新的sessionID,因此req.session.passport是未定义的。我必须显式设置axios.defaults.withCrendentails = true,然后一切正常。

相关问题