React 中无效的 CSRF 令牌但在 Postman 中有效

Invalid CSRF Token in React but valid in Postman

我有一个 Express 服务器,我正在其上生成 csrf 令牌。我的服务器看起来像这样

const csrfProtection = csrf({
  cookie: {
    httpOnly: true,
  },
});
server.use(express.json());
server.use(express.urlencoded({ extended: true }));
server.use(
  cors({
    origin: "http://localhost:3000",
    credentials: true,
  })
);
server.use(cookieParser());
server.use(csrfProtection);
...
//Other routes

我正在像这样发送令牌

export const csrf = (req, res) => {
  return res.send({ csrfToken: req.csrfToken() });
};

如果我从响应中获取它并将其添加到 Postman 中的 X-CSRF-Token header,那么我就可以很好地访问所有路由。但是当我在 React 中这样做时,我总是得到 invalid csrf token 错误

这就是我在 React 中获取令牌的方式

export const getCSRFToken = async () => {
  try {
    const { data } = await axios.get("/auth/csrf");
    axios.defaults.headers.post["X-CSRF-Token"] = data.csrfToken;
  } catch (error) {}
};

我在其他请求中使用 withCredentials: true 标志。我不知道我错过了什么。

也许你应该将 axios.defaults.headers.post["X-CSRF-Token"] = data.csrfToken 更改为 axios.defaults.headers.common["X-CSRF-Token"] = data.csrfToken

显然,问题是您还需要将 withCredentials 标志传递给获取 csrf 令牌的请求。所以这解决了问题。

export const getCSRFToken = async () => {
  try {
    const { data } = await axios.get("/auth/csrf", { withCredentials: true });
    axios.defaults.headers.common["X-CSRF-Token"] = data.csrfToken;
  } catch (error) {}
};