2017-04-05 5 views
2

Ich verwende Apollo (mit Graph Cool), Redux und Auth0 in einer React-Native App. Ich versuche, die Abfragen und Mutationen zu verzögern, bis der Header gesetzt ist.Apollo Client Verzögerung der Autorisierung Header

Der idToken wird im Async-Speicher gespeichert und ist daher ein Versprechen. Ich kann Redux nicht verwenden, um das Token zu übergeben, da dies eine zirkuläre Abhängigkeit erzeugen würde.

Wenn der Benutzer-Logins in zum ersten Mal oder dem Token abgelaufen ist, werden die Anfragen, die vor Header gesendet wird, was bedeutet, erhalte ich die Fehler Error: GraphQL error: Insufficient Permissionsenter image description here

Wie kann ich die Abfragen verzögern, bis das Token gefunden und zur Kopfzeile hinzugefügt? Ich habe drei Hauptlösungen gesucht:

  1. Hinzufügen forceFetch: true; Dies scheint Teil einer früheren Implementierung des Apollo-Clients zu sein. Auch wenn ich das Äquivalent finde, schlägt die App beim ersten Versuch immer noch fehl.
  2. Setzen Sie den Speicher (rehydrieren?) Beim Anmelden zurück. Dies ist immer noch asynchron, so sehe ich nicht, wie dies das Ergebnis beeinflussen könnte.
  3. Entfernen Sie alle Mutationen und Abfragen von der Anmeldung selbst, aber dies ist aufgrund des Fortschritts der App nicht möglich.

einige Auszüge:

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

und

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

Antwort

3

Ich bin nicht sicher, dies ohne eine Reproduktion App funktioniert, vor allem, weil ich eine App Ihrer Struktur Set nicht über zwar, aber du triffst diese Wettlaufbedingung, weil du next() außerhalb deiner asynchronen Kette anrufst.

Der Aufruf von next(), wo es derzeit ist, wird dem Client mitteilen, dass er mit der Anfrage fortfahren soll, auch wenn Ihr Token nicht gesetzt ist. Stattdessen warten wir, bis das Token zurückkommt und der Header gesetzt wird, bevor wir fortfahren.

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

Ja, das ist richtig. Weitere Informationen finden Sie im [Expo-Beispiel] (https://github.com/graphcool-examples/expo-auth0-instagram-example/blob/master/main.js), wo wir AsyncStorage ähnlich wie diese Antwort einrichten. – marktani

+0

Dies löst meine Antwort klar und prägnant. Vielen Dank. – Matty