programing

Axios 가로채기 및 비동기 로그인

skycolor 2023. 3. 13. 20:19
반응형

Axios 가로채기 및 비동기 로그인

토큰 인증을 구현하고 있습니다.나의access tokenN분마다 기한이 만료되고 나서refresh token로그인하여 새로운 것을 취득하기 위해 사용됩니다.access token.

API 호출에는 Axios를 사용합니다.요격기를 설치해서401응답:

axios.interceptors.response.use(undefined, function (err) {
  if (err.status === 401 && err.config && !err.config.__isRetryRequest) {
    serviceRefreshLogin(
      getRefreshToken(),
      success => { setTokens(success.access_token, success.refresh_token) },
      error => { console.log('Refresh login error: ', error) }
    )
    err.config.__isRetryRequest = true
    err.config.headers.Authorization = 'Bearer ' + getAccessToken()
    return axios(err.config);
  }
  throw err
})

기본적으로 401 응답을 대행 수신하기 때문에 로그인을 한 후 새로운 토큰을 사용하여 원래 거부된 요청을 다시 시도합니다.나의serviceRefreshLogin함수 호출setAccessToken()그 안에then블록. 하지만 문제는 이 모든 것이then블록은 다음보다 늦게 발생합니다.getAccessToken()리트라이는 유효기간이 지난 오래된 credential로 이루어집니다.

getAccessToken()그리고.getRefreshToken()브라우저에 저장된 기존 토큰을 반환하기만 하면 됩니다(localStorage, 쿠키 등을 관리합니다).

약속이 반환될 때까지 스테이트먼트가 실행되지 않도록 하려면 어떻게 해야 합니까?

(여기 Github 관련 문제가 있습니다.https://github.com/mzabriskie/axios/issues/266)

다른 약속을 사용하세요.d

axios.interceptors.response.use(undefined, function (err) {
    return new Promise(function (resolve, reject) {
        if (err.status === 401 && err.config && !err.config.__isRetryRequest) {
            serviceRefreshLogin(
                getRefreshToken(),
                success => { 
                        setTokens(success.access_token, success.refresh_token) 
                        err.config.__isRetryRequest = true
                        err.config.headers.Authorization = 'Bearer ' + getAccessToken();
                        axios(err.config).then(resolve, reject);
                },
                error => { 
                    console.log('Refresh login error: ', error);
                    reject(error); 
                }
            );
        }
        throw err;
    });
});

환경이 약속을 이행하지 않는 경우 polyfill을 사용합니다(예: https://github.com/stefanpenner/es6-promise).

단, getRefresh를 다시 쓰는 것이 좋을 수 있습니다.약속을 반환하고 코드를 단순화하기 위한 토큰

axios.interceptors.response.use(undefined, function (err) {

        if (err.status === 401 && err.config && !err.config.__isRetryRequest) {
            return getRefreshToken()
            .then(function (success) {
                setTokens(success.access_token, success.refresh_token) ;                   
                err.config.__isRetryRequest = true;
                err.config.headers.Authorization = 'Bearer ' + getAccessToken();
                return axios(err.config);
            })
            .catch(function (error) {
                console.log('Refresh login error: ', error);
                throw error;
            });
        }
        throw err;
});

데모 https://plnkr.co/edit/0ZLpc8jgKI18w4c0f905?p=preview

응답 대신 요청으로 할 수 있고 액세스 토큰이 만료되었을 때 서버에 영향을 주지 않기 때문에 더 깨끗할 수 있습니다.문서에서 복사:

function issueToken() {
  return new Promise((resolve, reject) => {
    return client({
      ...
    }).then((response) => {
      resolve(response);
    }).catch((err) => {
      reject(err);
    });
  });
}

client.interceptors.request.use((config) => {
  let originalRequest = config;
  if (tokenIsExpired && path_is_not_login) {
    return issueToken().then((token) => {
      originalRequest['Authorization'] = 'Bearer ' + token;
      return Promise.resolve(originalRequest);
    });
  }
  return config;
}, (err) => {
  return Promise.reject(err);
});

언급URL : https://stackoverflow.com/questions/35900230/axios-interceptors-and-asynchronous-login

반응형