oauth2.0 Passport:为什么在Azure Web App上部署时未定义“req.user”?

uyto3xhc  于 2023-03-22  发布在  其他
关注(0)|答案(1)|浏览(125)

我在一个Azure Web应用服务上运行了一个React前端,在另一个Azure Web应用服务上运行了一个节点后端。我已经设置了OAuth来通过Google对用户进行身份验证,使用Passport中间件,并使用cookie.session中间件设置了一个cookie。这一切都在我的本地机器上运行得很好。
但是,在Azure上,当我尝试从前端检索req.user的值时(我使用这些数据来控制对路由的访问)它返回undefined。我已经在后端的passport.serializeUser函数中控制台记录了user的值,并且在流程中的那个点上,它已经从Google检索了用户配置文件数据。cookie是在我的浏览器中创建的,但是,由于某种原因,这不是然后被传递到req.user在我的“成功”路线。
在本地运行时,所有内容都通过http运行。在Azure上,前端和后端Web服务都在Azure设置配置中设置为通过https运行。

这是我的前端函数,它检索req.user数据:

useEffect(() => {
    const getUser = () => {
      fetch(process.env.REACT_APP_BE_URL+"/auth/login/success", {
        method: "GET",
        credentials: "include",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json",
          "Access-Control-Allow-Credentials": true,
        },
      })
        .then((response) => {
          if (response.status === 200) return response.json();
          throw new Error("Authentication failed");
        })
        .then((resObject) => {
          setUser(resObject.user.id);
        })
        .catch((err) => {
          console.log(err);
        });
    };
    getUser();

后端index.js:

const express = require("express");
const app = express();
const cors = require("cors");
const cookieSession = require("cookie-session");
const passport = require("passport");
require("./config/passport");
require("dotenv").config();

app.use(express.json());
app.set("trust proxy", 2);

app.use(
  cookieSession({
    name: "session",
    keys: [process.env.COOKIE_SESSION_KEY],
    maxAge: 24 * 60 * 60 * 1000,
  })
);

app.use(passport.initialize());
app.use(passport.session());

app.use(
  cors({
    origin: process.env.HOST,
    methods: "GET,POST,PUT,DELETE",
    credentials: true,
  })
);

const db = require("./models");

// Routers
const authRouter = require("./routes/auth");
app.use("/auth", authRouter);

const successRouter = require("./routes/auth");
app.use("/login/success", successRouter);

const failedRouter = require("./routes/auth");
app.use("/login/failed", failedRouter);

db.sequelize.sync().then(() => {
  app.listen(process.env.PORT || 3001, () => {
    console.log("Server running");
  });
});

Passport配置(Passport.js):

require("dotenv").config();
const GoogleStrategy = require("passport-google-oauth20").Strategy;
const passport = require("passport");

passport.use(
  new GoogleStrategy(
    {
      clientID: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
      callbackURL: "/auth/google/callback",
      scope: ["profile"],
    },
    function (accessToken, refreshToken, profile, done) {
      done(null, profile);
    }
  )
);

passport.serializeUser((user, done) => {
  done(null, user);
  console.log("passport.serialization user = " + JSON.stringify(user));
});

passport.deserializeUser((user, done) => {
  done(null, user);
});

认证相关路由器(来自Auth.js):

router.get("/login/failed", (req, res) => {
  res.status(401).json({
    success: false,
    message: "Logon failure",
  });
});

router.get("/login/success", (req, res) => {
  // if (req.user) {
  res.status(200).json({
    success: true,
    message: "Logon successful",
    user: req.user,
  });
  console.log("req.user in router.get =" + JSON.stringify(req.user));
  // }
});

router.get(
  "/google/callback",
  passport.authenticate("google", {
    successRedirect: host + "/login/success",
    failureRedirect: host + "/login",
  })
);

router.get("/logout", (req, res) => {
  req.logout();
  res.redirect(host);
});

router.get("/google", passport.authenticate("google", { scope: ["profile"] }));

我在其他Stack Overflow帖子中读到,这个问题可能是由于Azure充当反向代理并阻止https流量,因此添加了推荐行:app.set("trust proxy", 2);在我的index.js文件,但这并没有解决问题。

hpxqektj

hpxqektj1#

如果其他人也遇到了同样的问题,我最终解决了这个问题(变通可能是一个更好的描述),通过设置我的前端和后端系统在我的主域的子域上运行。所以前端运行在www.example.com上app.mydomain.com,后端运行backend.mydomain.com。
我仍然不知 prop 体的根本原因问题是什么,但只是,这是做了不同的域的前端和后端.也许cors,也许与Azure作为一个反向代理,也许别的东西?!
无论如何,我会把这个留在这里,以防它帮助别人。如果有人最终确切地知 prop 体问题是什么,那么请添加一个答案或评论。

相关问题