未处理的拒绝(错误):GraphQL错误:未通过身份验证

时间:2020-06-04 23:57:34

标签: reactjs typescript graphql react-apollo apollo-client

我正在尝试使用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
});

有人可以帮助我弄清楚如何解决此问题?请

错误堆栈。 F

1 个答案:

答案 0 :(得分:1)

将 try/catch 块添加到您的注销中 ;)

<button onClick={
  async () => {
    try {
      await logout();
      setAccessToken('');
      await client!.resetStore();
    } catch (err) {
      console.log(err.message)
    }
  }}
>