2017-04-05 276 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