Клиент Apollo, задерживающий заголовок авторизации
Я использую Apollo (с Graph Cool), redux и Auth0 в приложении React-Native. Я пытаюсь отложить запросы и мутации, пока не будет установлен заголовок.
IdToken хранится в Async Storage и поэтому является обещанием. Я не могу использовать избыточность для передачи токена, потому что это создаст круговую зависимость.
Когда пользователь входит в систему в первый раз или токен истек, запросы отправляются до установки заголовка, что означает, что я получаю ошибку Error: GraphQL error: Insufficient Permissions
Как я могу отложить запросы, пока токен не будет найден и добавлен в заголовок? Я искал три основных решения:
- Добавить forceFetch: true; Похоже, это является частью более ранней реализации клиента Apollo. Даже если я найду эквивалент, приложение все равно не сможет с первой попытки получить.
- Сбросьте хранилище (регидратируйте?) При входе в систему. Это все еще асинхронно, поэтому я не понимаю, как это может повлиять на результат.
- Удалите все мутации и запросы из самого логина, но из-за прогресса приложения это невозможно.
Некоторые фрагменты:
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 ответ
Я не уверен, что это будет работать без приложения для воспроизведения, в основном потому, что у меня не настроено приложение с вашей структурой, но вы попали в это состояние гонки, потому что вы вызываете 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));
}
}]);