Apollo客户端延迟授权标题

时间:2017-04-05 18:32:49

标签: react-native redux graphql apollo graphcool

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

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

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

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

  1. 添加forceFetch:true;这似乎是早期Apollo客户端实现的一部分。即使我找到了相应的内容,该应用仍然会在第一次尝试获取时失败。
  2. 登录后重置商店(重新水合?)。这仍然是异步的,所以我不知道这会如何影响结果。
  3. 从登录本身删除所有突变和查询,但由于应用程序的进展,这是不可行的。
  4. 一些片段:

    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),
      )
    );
    

1 个答案:

答案 0 :(得分:3)

我不确定这会在没有复制应用程序的情况下运行,主要是因为我没有设置您的结构的应用程序,但是因为您正在呼叫下一次这种竞争条件()在异步链之外。

调用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));   
  }
}]);