React前端使用环境变量API_URL获取用户详情失败,登录接口却正常
前端获取用户详情接口失败问题排查与解决
我在前端编写了UserDetails异步函数获取服务器用户详情,但无法正常获取数据。直接使用环境变量拼接URL请求失败,但配置proxy后用相对路径请求正常;同时相同环境变量拼接方式的登录POST接口(useLogin钩子)却能正常运行。相关代码如下:
问题代码:UserDetails函数
const UserDetails = async () => { const apiUrl = process.env.REACT_APP_API_URL; try { console.log(`${apiUrl}`); console.log("fetching"); const response = await fetch(`${apiUrl}/api/user/getUserDetails`); if (!response.ok) { throw new Error(`response was not ok. Status: ${response.status}`); } const data = await response.json(); return data.userDetails; } catch (err) { console.error("Error:", err); throw err; } }; export default UserDetails;
正常工作的登录钩子useLogin
export const useLogin = () => { const [error, setError] = useState(null); const [isLoading, setIsLoading] = useState(null); const { dispatch } = useAuthContext(); const apiUrl = process.env.REACT_APP_API_URL; const login = async (email, password) => { setIsLoading(true); setError(null); console.log("login request made", email, password); const response = await fetch(`${apiUrl}/api/user/login`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ email, password }), }); const json = await response.json(); const userRole = json.userRole; console.log("User Role:", userRole); if (!response.ok) { setIsLoading(false); setError(json.error); } if (response.ok) { console.log("logging in", json); // save the user to local storage localStorage.setItem("user", JSON.stringify(json)); // update the auth context dispatch({ type: "LOGIN", payload: { ...json, role: userRole } }); // update loading state setIsLoading(false); } }; return { login, isLoading, error }; };
.env配置
REACT_APP_API_URL=http://localhost:4000
服务器端server.js代码
require("dotenv").config(); const mongoose = require("mongoose"); const express = require("express"); var cors = require("cors"); const userRoutes = require("./routes/user"); const bookRoutes = require("./routes/Book"); const publisherrightRoutes = require("./routes/Publisherright"); const cookieParser = require("cookie-parser"); const app = express(); app.use(cors()); const stripe = require("stripe")( "sk_test_51O12iqAQvidGp1QOJDPSU2UlOCAjNtA8CPjbH4X6RssKvOKxLCuuflXvlHfLEWXBg4U4UIIL4Wypv74pFmrFDGXQ00qNuRF96x" ); app.get("/", function (req, res) { res.send("Hello world!"); }); //middlware app.use(express.json()); app.use(cookieParser()); //routes app.use("/api/user", userRoutes); app.use("/api/book", bookRoutes); app.use("/api/publisherright", publisherrightRoutes); app.post("/create-subscription", async (req, res) => { const customer = await stripe.customers.create({ email: req.body.email, source: req.body.stripeToken, }); const subscription = await stripe.subscriptions.create({ customer: customer.id, items: [{ plan: req.body.plan }], }); res.json({ subscription }); }); mongoose .connect(process.env.MONGO_URL) .then(() => { app.listen(process.env.PORT, function () { console.log("Connected to db and listening on port ", process.env.PORT); }); }) .catch((error) => { console.log(error); });
潜在原因分析
- CORS 配置未携带凭证:登录接口是POST请求,获取用户详情是GET请求,后者可能需要携带登录后的Cookie凭证。服务器端
cors()默认配置不允许跨域请求携带凭证,直接用完整URL请求时,浏览器会因CORS策略拦截请求;而proxy方式属于同源请求,不会触发CORS检查。 - GET请求未传递身份验证信息:登录后用户身份信息通常存在Cookie中,
UserDetails函数的fetch请求未配置credentials: 'include',导致服务器无法识别用户身份,返回401或其他错误。 - 接口权限校验问题:
/api/user/getUserDetails路由可能存在权限校验逻辑漏洞,未正确读取请求中的身份信息,导致无有效响应返回。
解决方法
修改fetch请求携带凭证
在UserDetails函数的fetch中添加凭证配置,确保跨域请求时携带Cookie:const response = await fetch(`${apiUrl}/api/user/getUserDetails`, { credentials: 'include' });调整服务器端CORS配置
修改服务器端cors中间件,明确允许携带凭证并指定前端origin:app.use(cors({ origin: "http://localhost:3000", // 替换为你的前端实际地址 credentials: true }));验证接口权限逻辑
检查/api/user/getUserDetails路由的权限校验代码,确认是否正确读取Cookie或请求头中的身份信息,避免因校验失败导致无响应。
内容的提问来源于stack exchange,提问作者sanuth menuka
相关产品推荐
相关产品推荐

