如何在上下文中使用JWT令牌使查询无效?



我使用短期JWT令牌访问我的API;令牌需要每10分钟左右提取一次。我的根App组件每隔一段时间获取令牌,将其设置为本地状态并传递到所有组件都可以访问的上下文中。

function App() {
const queryClient = new QueryClient()
const [auth, setAuth] = useState({
isValid: null,
token: null,
user: null
})
//Get User and API Token
useEffect(() => {
const fetchToken = async () => {
try {
const fetchItem = await fetch(
'http://someLocalHost:5000/user',
{
credentials: 'include'
}
)
const fetchResponse = await fetchItem.json();
console.log(fetchResponse)
if (fetchItem.status === 200) {
setAuth({
isValid: true,
token: fetchResponse['token'],
user: fetchResponse['user']
});
}
} catch {
setAuth({isValid: false});
}
};
var intervalCall;
if (auth.isValid === true) {
intervalCall = setInterval(fetchToken, 200000);
} else if (auth.isValid === false) {
return
} else {
fetchToken();
}
return () => {
clearInterval(intervalCall);
};
}, [auth.isValid]);
const authContext = {
user: auth.user,
token: auth.token,
login: (props) => {
setAuth({
isValid: true,
token: props.token,
user: props.user,
})
},
logout: () => {
setAuth({
isValid: false
})
}
}

return (
<div>
<QueryClientProvider client={queryClient}>
<AuthContext.Provider value={authContext}>
<Router>
<Nav />
<main>
<Switch>
<Route path="/" exact component={Index} />
</Switch>
</main>
</Router>
</AuthContext.Provider>
</QueryClientProvider>
</div>
);
}
export default App

我使用react-query来获取、存储和更新API数据。我的组件通常看起来像这样:

function Index() {
const auth = useContext(AuthContext);
);
const usersQuery = useQuery(
'users',
() => fetchData({url: '/users', token: auth.token})
);

return (
<div>
<UserList list={usersQuery.data} />
<NewUser />
</div>
)
}
export default Index

我真的很喜欢invalidateQueries引起数据重取的能力。New User组件使用突变,然后使'users'查询无效。

function NewUser() {
const auth = useContext(AuthContext);
const queryClient = useQueryClient()
const newUserMutation = useMutation(formData => fetchPUT({
url: 'new_user',
type: 'PUT',
token: auth.token,
formData: formData
}), {
onSuccess: () => {
queryClient.invalidateQueries('users');
}
});
const addUser = (user_id) => {
var fetchData = new FormData();
fetchData.append('user_id', user_id);
newUserMutation.mutate(fetchData);
};
return (
<div>
<button onClick={() => addUser('someUserID')}>Create New User</button>
</div>
)
}
export default NewUser

这个工作很好,直到200000ms过去,我的根组件获取一个新的身份验证令牌并更新上下文。一旦上下文更新,invalidateQueries就不会触发,refetchOnWindowFocus也不会触发。只有刷新才能修复它。我假设这是由反应-查询哈希查询键的方式引起的,所以我试图将身份验证令牌和url添加到查询键数组中,然后在我的fetch函数中使用queryKeys

const usersQuery = useQuery(
['users', {url: '/users', token: auth.token}],
fetchData
);

但无济于事。有人知道这是什么原因吗?是我的结构吗?每次上下文更改时都重新安装Index组件,但对于许多嵌套组件,这将成为一种痛苦。

这是我的组件树的简化结构,只显示相关代码,实际结构更嵌套和复杂。

明白了。最重要的是结构。
如果其他人遇到这个。解决方案如下:

const queryClient = new QueryClient()

每当App组件的状态发生变化时,都会创建一个新的QueryClient实例。新客户端没有附加任何旧的挂载查询。最终将所有身份验证移动到子组件,并将QueryClientQueryClientProvider留在根App元素中,该元素永远不会重新渲染或重新加载

相关内容

  • 没有找到相关文章

最新更新