我正在尝试使用apollo客户端在React应用程序中注销时重置存储,以清除当前用户信息。但是用Unhandled Rejection (Error): GraphQL error: Not authenticated
重置错误client!.resetStore()
会引发
import React from 'react';
import { Link } from 'react-router-dom';
import { useMeQuery, useLogoutMutation } from '../../generated/graphql';
import { setAccessToken } from '../../accessToken';
interface Props {}
export const Navigation : React.FC<Props> = () =>{
const { data, loading } = useMeQuery();
const [logout, {client}] = useLogoutMutation();
let body: any = null;
if (loading) {
body = null;
} else if (data && data.me) {
body = <div>welcome {data.me.email} </div>;
} else {
body = <div>Not logged in</div>;
}
return (
<header>
<div>
<Link to="/login">Login</Link>
</div>
<div>
{!loading && data && data.me ?
<button onClick= {
async () => {
await logout();
setAccessToken('');
await client!.resetStore();
}}
>
Logout
</button>
: null
}
</div>
{ body }
</header>
)
}
我的apollo客户端配置为:
const cache = new InMemoryCache({});
const authLink = new ApolloLink((operation, forward) =>
new Observable(observer => {
let handle : any;
Promise.resolve(operation)
.then((operation) => {
const accessToken = getAccessToken();
if (!accessToken) return;
operation.setContext({
headers: { authorization: `bearer ${accessToken}` }
});
})
.then(() => {
handle = forward(operation).subscribe({
next: observer.next.bind(observer),
error: observer.error.bind(observer),
complete: observer.complete.bind(observer),
});
})
.catch(() => {observer.error.bind(observer)});
return () => {
if (handle) handle.unsubscribe();
};
})
);
const requestlink = new HttpLink({
uri: 'http://localhost:4000/graphql',
credentials: 'include'
});
const errorLink = onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.forEach(({ message, locations, path }) =>
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
)
);
if (networkError) console.log(`[Network error]: ${networkError}`);
});
const refreshTokenLink = new TokenRefreshLink({
accessTokenField: 'accessToken',
isTokenValidOrUndefined: () => {
const token = getAccessToken();
if (!token) return true;
try {
const {exp} = JwtDecode(token);
if (Date.now() >= exp * 1000) return false;
return true;
} catch(error) {
return false;
}
},
fetchAccessToken: () => {
return fetch('http://localhost:4000/refresh_token', {
method: 'POST',
credentials: 'include'
});
},
handleFetch: accessToken => {
setAccessToken(accessToken)
},
handleError: err => {
console.warn('Your refresh token is invalid. Try to relogin');
console.error(err);
}
});
const client = new ApolloClient({
link: ApolloLink.from([
errorLink,
refreshTokenLink,
authLink,
requestlink,
]),
cache
});
有人可以帮助我弄清楚如何解决此问题?请
答案 0 :(得分:1)
将 try/catch 块添加到您的注销中 ;)
<button onClick={
async () => {
try {
await logout();
setAccessToken('');
await client!.resetStore();
} catch (err) {
console.log(err.message)
}
}}
>