node.js - Passport session 适用于 Postman,但不适用于浏览器

标签 node.js reactjs express axios passport.js

我一直在尝试使用 React 和 Node 进行登录。我使用 axios 从前端发送请求,并在后端使用 Express with Passport 发送请求。

此代码适用于 Postman,但不适用于浏览器。当我从浏览器发送请求时,req.session.passport 未定义,即未调用 deserialize() 。 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');
})

带 Passport 代码的 express

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");

    });

最佳答案

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

关于node.js - Passport session 适用于 Postman,但不适用于浏览器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55247812/

相关文章:

node.js - 如何记住客户的数据?

javascript - babel React 查找模块时出现问题

javascript - 如何使用 Node.js 解压文件

reactjs - Material-ui 按钮中的 Font Awesome 图标

javascript - 等待来自另一个 mobx 存储的异步数据

node.js - 如何使用 Node http-proxy 代理到根路径

node.js - 如何使用 Dropbox Lepton Node JS 包压缩图像

Javascript Node 从 CSV 文件中读取数据并将数据存储到对象中

javascript - 然后服务 worker 注册 - 未定义不是一个函数

node.js - Node : Passing function to a Promise