使用`apollo-link-error`无法处理过期的令牌

时间:2019-07-21 22:12:23

标签: javascript apollo react-apollo

我正在为我的一个项目尝试Apollo,但是我对如何处理刷新令牌深感固执。我想要的是以下流程:

  1. 登录到我的网站后,我们获取新的访问权限和刷新令牌,并保存在localStorage中(目前,稍后使用cookie)。
  2. 在随后的使用authLink的请求中使用访问令牌,请参见下面的代码。
  3. 令牌过期后,我们会从API中收到错误消息,并使用errorLink触发令牌刷新流程。
  4. 刷新访问令牌后,我们将使用新的访问令牌尝试原始请求。

我见过有类似情况和需求的人,但我无法使其正常工作。以下是我基于答案here的最新尝试,但实际上并没有尝试使用新令牌重试原始请求。欢迎任何帮助或提示!

const authLink = setContext((_, { headers }) => {
  const token = localStorage.getItem("auth-token");

  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : ""
    }
  };
});

const errorLink = onError(
  ({ graphQLErrors, networkError, operation, forward }) => {
    if (graphQLErrors)
      graphQLErrors.map(({ message }) => {
        switch (message) {
          case "invalid_token":
            return new Observable(observer => {
              refreshToken()
                .then(({ data }) => {
                  localStorage.setItem(
                    "auth-token",
                    data.refreshToken.token
                  );
                  const oldHeaders = operation.getContext().headers;
                  const token = localStorage.getItem("auth-token");
                  operation.setContext(({ headers = {} }) => ({
                    headers: {
                      ...headers,
                      authorization: token ? `Bearer ${token}` : ""
                    }
                  }));
                })
                .then(() => {
                  const subscriber = {
                    next: observer.next.bind(observer),
                    error: observer.error.bind(observer),
                    complete: observer.complete.bind(observer)
                  };

                  // Retry last failed request
                  forward(operation).subscribe(subscriber);
                })
                .catch(e => {
                  observer.error(e);
                });
            });
        }
      });
    if (networkError) console.log(`[Network error]: ${networkError}`);
  }
);

const refreshToken = () => {
  return client.mutate({
    mutation: REFRESH_AUTH_TOKEN
  });
};

const link = ApolloLink.from([errorLink, authLink, httpLink]);

0 个答案:

没有答案