刷新令牌时 Apollo Graphql 不更新 useQuery

Apollo Graphql when refreshing token doesn't update useQuery

我面临下一个问题: 我有一个用于获取 usersData

的 useQuery 挂钩

GET_USER_INFO 使用查询

const { data:dataGetUserInfo, loading:loadingQuery, error:errorQuery,refetch  } = useQuery(GET_USER_INFO, {variables: {
            getUserInfoInfoId: userId
        }});

并且我想在访问令牌过期时刷新访问和刷新令牌。为此,我在 apollo-client.ts 中完成了 errorLink,它在需要时调用刷新功能,然后调用我的 GET_USER_INFO useQuery

阿波罗-client.ts

const getNewToken =  () => {
    let refreshToken

        refreshToken = localStorage.getItem("REFRESH");

    return client.mutate({
        mutation: REFRESH_TOKEN,
        variables:{
            refreshTokenRefreshToken : refreshToken,
        }
    })
        .then((res) => {
            localStorage.clear();
            const { accessToken,refreshToken } = res.data.refreshToken;
            localStorage.setItem('REFRESH',refreshToken)
            localStorage.setItem('AUTHORIZATION',accessToken)
            return res.data;
        }).catch((err)=>{
            console.log(err)
            
        })

};



const errorLink = onError(
    ({ graphQLErrors, networkError, operation, forward }) => {
        if (graphQLErrors) {
            for (let err of graphQLErrors) {

                switch (err.extensions?.code) {
                    
                    case "UNAUTHENTICATED" :
                        console.log('aa')
                        return fromPromise(
                            getNewToken().catch((error) => {
                                localStorage.clear();
                                // Handle token refresh errors e.g clear stored tokens, redirect to login
                                return;
                            })
                        )
                            .filter((value) => Boolean(value))
                            .flatMap(({accessToken, refreshToken}) => {

                                const oldHeaders = operation.getContext().headers;
                                // modify the operation context with a new token
                                operation.setContext({
                                    headers: {
                                        ...oldHeaders,
                                        authorization: `Bearer ${accessToken}`,
                                    },
                                });

                                // retry the request, returning the new observable
                                return forward(operation);
                            });
                   

                }
            }
        }
    }
);



const authLink = setContext((_, { headers }) => {
  return {
    headers: {
      ...headers,
      authorization: localStorage.getItem("AUTHORIZATION") ? `Bearer ${localStorage.getItem("AUTHORIZATION")}` : "",
    },
  };
});




const client = new ApolloClient({
  link: ApolloLink.from([errorLink,authLink, httpLink]),
})

问题是: 成功刷新令牌后,它不会在我的 useQuery 中重新获取数据

顺便说一句,它又做了一个失败的请求,我不知道为什么

您可以使用retry link再次运行查询。

您应该以重试 link 最外 link 的方式链接您的 link,这样您就可以等待错误 link 获取令牌。查看 custom strategies,您可以在此处对错误对象中的特定状态代码做出反应或收听自定义 属性,错误 link 可以附加到 operation目的。这样您甚至可以在令牌刷新失败时阻止重新获取(例如,因为重新获取令牌也超时)。

link 也都是开源的,所以如果链接它们对你来说真的不起作用,你也可以开发自己的 refetch+retry link 通过结合两者的代码 links.