【发布时间】:2021-12-02 08:56:17
【问题描述】:
我需要有关 csrf 令牌问题的帮助。 现在在第一次渲染时,我正在发送获取 CSRF 令牌的请求,然后将其设置为默认标头,如下所示。
const { data } = await publicAxios.get('/csrf-token');
publicAxios.defaults.headers['X-CSRF-Token'] = data.csrfToken;
authAxios.defaults.headers['X-CSRF-Token'] = data.csrfToken;
问题是在第一次渲染时我也在发送另一个 POST 请求,但是所有请求都失败并出现 403 代码,因为这些请求没有“X-CSRF-Token”标头。 我该怎么做才能解决这个问题?
import axios from "axios";
import { createContext, useEffect } from "react";
const FetchContext = createContext();
const { Provider } = FetchContext;
const FetchProvider = ({ children }) => {
const publicAxios = axios.create({ baseURL: '/api' })
const authAxios = axios.create({ baseURL: '/api' })
authAxios.interceptors.response.use(
response => {
return response
},
error => {
return Promise.reject(error)
}
);
useEffect(() => {
const getCsrfToken = async () => {
try {
const { data } = await publicAxios.get('/csrf-token');
publicAxios.defaults.headers['X-CSRF-Token'] = data.csrfToken;
authAxios.defaults.headers['X-CSRF-Token'] = data.csrfToken;
} catch (err) {
console.log(err)
}
};
getCsrfToken();
}, [authAxios, publicAxios]);
return (
<Provider value={{ authAxios, publicAxios }}>
{children}
</Provider>
);
};
export { FetchContext, FetchProvider }
这就是我的使用方式
import { useContext, useEffect, useState } from "react";
import { FetchContext } from "../Context/index";
const UsersList = ({ children }) => {
const { authAxios } = useContext(FetchContext);
const [userList, setUserList] = useState(null);
useEffect(() => {
async function getUsers() {
try {
const { data } = await authAxios.post(
'/users/list'
);
if (Array.isArray(data) && data.length > 0) {
setUserList(data)
} else {
setUserList('No');
}
} catch (e) {
console.log(e)
setUserList('Error')
}
}
getUsers()
}, [authAxios]);
return (
<div>
hello
</div>
)
}
【问题讨论】:
-
您是在获取请求之前,并行还是严格之后发送该发布请求?
-
@apokryfos 我正在并行发送。所有其他请求都是使用通过 Provider 从上述代码导出的 authAxios 从不同组件发起的。所以我不明白如何在获得 csrf 令牌后发送所有请求。
-
根据您的应用程序结构,这可能很简单,也可能是个大问题。由于您使用的是 react,那么也许您可以在 promise 中检索 csrf 令牌,然后使用 context 与所有组件共享。然后每个组件可以在发送任何需要它的请求之前等待令牌,但是如果您的设置允许它,您可能会找到一个更简单的解决方案,注意相同的承诺对象只解析一次
-
@apokryfos 感谢您的指出,让我试试类似的方法。
-
还可以查看useContext 钩子,了解使用功能组件时的情况
标签: reactjs axios csrf-token