2017-04-05 275 views
2

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

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

当首次或令牌用户登录已过期,查询是头前发送设置,这意味着我得到的错误Error: GraphQL error: Insufficient Permissionsenter image description here

我怎样才能延缓查询,直到令牌找到并添加到标题?我一直在寻找三种主要的解决方案:

  1. Add forceFetch:true;这似乎是阿波罗客户早期实施的一部分。即使我找到相同的内容,该应用仍然会在首次尝试抓取时失败。
  2. 登录后重置商店(rehydrate?)。这仍然是异步的,所以我不明白这会如何影响结果。
  3. 从登录本身中删除所有突变和查询,但由于应用程序的进展,这是不可行的。

一些片段:

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

回答

3

我不能肯定这将不再现应用程序的工作,主要是因为我没有你的结构集的应用程序但是由于你在异步链之外调用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)); 
    } 
}]); 
+0

是的,没错。有关更多参考资料,请查看[世博会示例](https://github.com/graphcool-examples/expo-auth0-instagram-example/blob/master/main.js),我们将AsyncStorage设置为类似于此答案。 – marktani

+0

这清楚而简洁地解答了我的答案。谢谢。 – Matty