【问题标题】:Apollo Client Delaying the Authorization HeaderApollo 客户端延迟授权标头
【发布时间】:2017-08-31 12:45:42
【问题描述】:

我在 React-Native 应用程序中使用 Apollo(带有 Graph Cool)、redux 和 Auth0。我正在尝试延迟查询和突变,直到设置标头。

idToken 存储在异步存储中,因此是一个承诺。我不能使用 redux 来传递令牌,因为那样会产生循环依赖。

当用户第一次登录或令牌过期时,查询是在设置标头之前发送的,这意味着我收到错误Error: GraphQL error: Insufficient Permissions

如何延迟查询,直到找到令牌并将其添加到标头?我一直在寻找三个主要的解决方案:

  1. 添加 forceFetch: true;这似乎是 Apollo 客户端早期实现的一部分。即使我找到了等价物,该应用在第一次尝试获取时仍然失败。
  2. 登录时重置存储(补水?)。这仍然是异步的,所以我看不出这会如何影响结果。
  3. 从登录本身中删除所有突变和查询,但由于应用程序的进度,这是不可行的。

一些sn-ps:

const token = AsyncStorage.getItem('token');
const networkInterface = createNetworkInterface({ uri:XXXX})

//adds the token in the header
networkInterface.use([{
    applyMiddleware(req, next) {
        if(!req.options.headers) {
            req.options.headers = {}
        }
        if(token) {
            token
                .then(myToken => {
                    req.options.headers.authorization = `Bearer ${myToken}`;
                })
                .catch(err => console.log(err));   
        }
        next(); // middleware so needs to allow the endpoint functions to run;
    },
}]);

// create the apollo client;
const client = new ApolloClient({
    networkInterface,
    dataIdFromObject: o => o.id
});

const store = createStore(
  combineReducers({
    token: tokenReducer,
    profile: profileReducer,
    path: pathReducer,
    apollo: client.reducer(),
  }),
  {}, // initial state
  compose(
      applyMiddleware(thunk, client.middleware(), logger),
  )
);

【问题讨论】:

    标签: react-native redux graphql apollo graphcool


    【解决方案1】:

    如果没有复制应用程序,我不确定这是否可以工作,主要是因为我没有设置您的结构的应用程序,但是您遇到了这种竞争条件,因为您在异步之外调用 next()链。

    在当前位置调用 next() 将告诉客户端继续请求,即使您的令牌未设置。相反,让我们等到令牌返回并设置标头后再继续。

    networkInterface.use([{
      applyMiddleware(req, next) {
        if(!req.options.headers) {
          req.options.headers = {}
        }
        AsyncStorage.getItem('token')
          .then(myToken => {
             req.options.headers.authorization = `Bearer ${myToken}`;
          })
          .then(next)  // call next() after authorization header is set.
          .catch(err => console.log(err));   
      }
    }]);
    

    【讨论】:

    • 是的,没错。如需更多参考,请查看Expo example,我们设置 AsyncStorage 的位置与此答案类似。
    • 这清楚而简洁地解决了我的答案。谢谢。
    猜你喜欢
    • 2019-07-01
    • 2020-10-19
    • 2020-01-20
    • 1970-01-01
    • 2022-06-14
    • 2020-01-24
    • 2018-10-14
    • 2021-04-07
    • 2018-02-14
    相关资源
    最近更新 更多