1

我在我的项目中使用 urql GraphQL 客户端。登录后,它不会自动在授权标头中添加令牌,因为它应该。我必须刷新一次页面,然后在标题中设置令牌。我已经阅读了文档,似乎无法弄清楚我做错了什么。

这是我的实现:

export const urqlClient = createClient({
  url: `${url}`,
  exchanges: [
    dedupExchange,
    cacheExchange,
    authExchange({
      getAuth: async ({ authState, mutate }: any) => {

        // for initial launch, fetch the auth state from storage (local storage, async storage etc)
        const token = Cookies.get('token');
        if (!authState) {
          if (token) {
            return { token };
          }
          return null;
        }

        // refresh token
        const decoded = jwt_decode<MyToken>(token as any);
        if (typeof decoded.exp !== 'undefined' && decoded.exp < Date.now() / 1000) {
          const user = firebase.auth().currentUser;
          if (user) {
            await user.getIdToken();
          }
        }

        //auth has gone wrong. Clean up and redirect to a login page
        Cookies.remove('token');
        await signOut();
      },
      addAuthToOperation: ({ authState, operation }: any) => {
        // the token isn't in the auth state, return the operation without changes
 
        if (!authState || !authState.token) {
          return operation;
        }

        // fetchOptions can be a function (See Client API) but you can simplify this based on usage
        const fetchOptions =
          typeof operation.context.fetchOptions === 'function'
            ? operation.context.fetchOptions()
            : operation.context.fetchOptions || {};

        return makeOperation(operation.kind, operation, {
          ...operation.context,
          fetchOptions: {
            ...fetchOptions,
            headers: {
              ...fetchOptions.headers,
              Authorization: `Bearer ${authState.token}`,
            },
          },
        });
      },
    }),
    fetchExchange,
  ]
});

我在这里做错了什么?谢谢

4

2 回答 2

2

您还没有配置任何信号用于再次authExchange触发该getAuth功能。理解这一点的关键是getAuth触发器的函数在三种不同的情况下:

  • 启动时
  • whenwillAuthError在操作前返回 true
  • didAuthError结果后返回真

所以你有两个选择;您需要确保willAuthErrordidAuthError可以识别您已登录,如果您的下一个操作返回身份验证错误,这将是自动的。文档记录了如何设置此选项来执行此操作。

另一种方法是返回一个可变对象getAuth,您可以在getAuth函数外部进行更新,以更新它或确保willAuthError触发器

于 2021-07-08T10:08:54.127 回答
2

你不见了

凭据:“包括”

headers: {
              ...fetchOptions.headers,
              Authorization: `Bearer ${authState.token}`,
            },
credentials: 'include', // missing this
于 2021-06-30T11:15:59.767 回答