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