Способ обработки refre sh токена - PullRequest
1 голос
/ 31 января 2020

Я работаю над функцией входа в систему и у меня возникают проблемы при обновлении токена sh.

Когда срок действия токена истекает, я отправляю запрос на обновление токена sh, удалите старый токен и сохраните новый токен в AsyncStorage.

После успешного входа в систему должны функционировать функции A и B. Функция A использует новый токен для выполнения своего запроса. функция B сообщает, что необходимо обновить sh токен, поэтому сделайте запрос на обновление sh токена (запрос успешно выполнен, токен refre sh), но токен, который запрос A использует сейчас invalid - I думаю, что это происходит из-за асинхронного

Это мой код, который используется для refre sh токена:

axiosInstance.interceptors.response.use(
  function (response) {
    return response;
  },
  async function (error) {
    if (error.response.status === CODE_TOKEN_EXPIRED) {
      try {
        const token = await authenticationService.getRefreshToken();
        const response = await authenticationService.refreshToken(token);
        await authenticationService.removeToken();
        await authenticationService.storeToken(response.data.params.access_token);
        await authenticationService.storeRefreshToken(response.data.params.refresh_token);
        error.config.headers.Authorization = 'Bearer ' + response.data.params.access_token;
        error.response.config.headers['Authorization'] = 'Bearer ' + response.data.params.access_token;
        return axiosInstance(error.config);
      } catch (err) {
        console.log(2, err);
        await authenticationService.removeToken();
        navigationService.navigate('LoginForm');
      }
    }
    return Promise.reject(error);
  }
);

Кто-нибудь знает, как обрабатывать какой асинхронный вызов для refre sh токена?

Ответы [ 2 ]

0 голосов
/ 31 января 2020

Я реализовал тот же сценарий в API выборки. Вы также можете сделать то же самое в Ax ios API. Попробуйте это, чтобы избежать концепции перехватчика.

Api.ts

export const api = ({ method, url, body, isProtected = true }) => {
  return new Promise((resolve, reject) => {
    const payload = {
      method,
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json'
      }
    };
    if (body !== null) {
      (payload as any).body = JSON.stringify(body);
    }

        /**
        * "isProtected" is used for API call without authToken
        */

    if (isProtected) {
      AsyncStorage.getItem(ACCESS_TOKEN).then(accessKey => {
        (payload.headers as any).Authorization = `Bearer ${accessKey}`;
        fetch(url, payload)
          .then((response: any) => {

                        /*
                        * 419 status denotes the timeout of authToken
                        */

            if (response.status == 419) {
              // refresh token
              AsyncStorage.getItem(REFRESH_TOKEN).then(refreshKey => {

                const payloadRef = {
                  method: 'POST',
                  headers: {
                    Accept: 'application/json',
                    'Content-Type': 'application/json',
                    Authorization: 'Bearer ' + refreshKey
                  }
                };
                                /*
                                * This call refresh the authToken using refreshing call to renew the authToken
                                */
                fetch(URL.baseUrl + "/refresh", payloadRef)
                  .then((response: any) => response.json())
                  .then(response => {

                                        /*
                                        * if refresh token expired. redirect to login page
                                        */

                    if (response.status !== codes.SUCCESS) {
                      if (!User.sessionOver) {
                        User.sessionOver = true;
                        Alert.alert(
                          'Alert',
                          'Session Timeout',
                          [
                            {
                              text: 'Get back to Login',
                              onPress: () => {
                                // get to Login page
                              }
                            }
                          ],
                          { cancelable: false }
                        );
                      }
                    } else if (response.status == codes.SUCCESS) {

                                            /*
                                            * If refresh token got refreshed and set it as authToken and retry the api call.
                                            */

                      AsyncStorage.setItem(ACCESS_TOKEN, response.payload.access_key).then(() => {
                        (payload.headers as any).Authorization = 'Bearer ' + response.payload.access_key;
                        fetch(url, payload)
                          .then(response => response.json())
                          .then(response => {
                            if (response.status == codes.SUCCESS) {
                              resolve(response);
                            }
                          })
                          .catch(error => {
                            reject(error);
                          });
                      });
                    }
                  });
              });
            } else {
              resolve(response.json());
            }
          })
          .catch(error => {
            reject(error);
          });
      });
    } else {
      fetch(url, payload)
        .then((response: any) => {
          response = response.json();
          resolve(response);
        })
        .catch(error => {
          reject(error);
        });
    }
  });
};

MovieService.ts

import { api } from '../services/api';
import { URL } from '../config/UrlConfig';

const getMovies = () => {
  const method = 'GET';
  const url = URL.baseUrl + '/v1/top/movies';
  const body = null;
  const isProtected = true;
  return api({ method, url, body, isProtected });
};

export { getMovies };
0 голосов
/ 31 января 2020

Сначала вам нужно проверить, заменяете ли вы токен на правильный экземпляр ios. Необходимо изменить заголовок авторизации в конфигурации error.response, как вы это сделали, но также и для экземпляра main ax ios (если он у вас есть), например: axios.defaults.headers.common["Authorization"] = "Bearer " + access_token;

Если выполняется несколько параллельных запросов, которые, возможно, потребуется отложить после обновления токена, проблема и ответ становятся сложными, но проверьте это gist с полным refre sh logi c с топором ios.

...