일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
Tags
- ios
- react-hook-form
- 프로그래머스
- Flipper
- react-native-image-picker
- 유니온타입
- 파스에러
- React
- 크라코
- javascript
- 리액트네이티브
- slice
- js
- Typescript
- craco
- 코드숨
- 제네릭타입
- reactnative
- 타입스크립트
- sort( )
- react-native
- 배열
- 자료구조와알고리즘
- react-native-camera-roll
- 자바스크립트
- react-native-vision-camera
- Android
- 리액트
- 모던자바스크립트
- 리액트쿼리
Archives
- Today
- Total
KassyLog
Refresh Token 본문
JWT 토큰 인증 방식은 제 3자에게 토큰이 탈취되는 경우 보안에 취약하다는 단점이 있어 토큰에 유효기간을 부여하여 보안을 강화하게 되는데, 유효기간이 짧으면 사용자는 계속 로그인을 다시 해야하기 때문에 불편해 진다. 여기서 사용할 수 있는 것이 Refresh Token을 활용한 토큰 리프레시다.
다른 블로그를 참고해서 가져온 사진은 이와 같다.
여기서 내가 나만의 언어로 생각해본 리프레시 토큰의 인터셉터 작동과정을 대화체로 설명해보겠다!
서버: 너 토큰 만료 됐으니까 리프레시토큰으로 너인거 증명해~
클라이언트: 앗! 나 리프레시토큰 챙겨왔어! 얼렁 통과시켜줘
서버: 음~ 알겠어. 다음에 또 챙겨와~
alert은 sweetalert2 라이러리를 활용해서 구현했으며 내가 실제로 구현한 코드는 아래와 같다
//Api.js
import axios from "axios";
import Swal from "sweetalert2";
import { useState } from "react";
export const api = axios.create({
baseURL: process.env.REACT_APP_BASE_URL,
headers: {
"content-type": "application/json;charset=UTF-8",
accept: "application/json",
},
});
//요청 api에 토큰을 실어줌
api.interceptors.request.use((config) => {
// console.log("----------------> request", config);
const token = sessionStorage.getItem("accessToken");
// console.log("액세스토큰나오니?", token);
config.headers.common["Authorization"] = `${token}`;
return config;
});
// response interceptors
api.interceptors.response.use(
(response) => {
// console.log("--------------> response", response);
return response;
},
async (error) => {
const { config } = error;
const originalRequest = config;
// 401 에러 발생시 액세스토큰 만료되었을 때, 리프레시토큰 보내기
if (error.response.data.message === "Access token is not valid") {
// console.log("1. 액세스토큰 만료됐으니 리프레시를 보내거라");
const refreshToken = sessionStorage.getItem("refreshToken");
// console.log("2. 리프레시 나오니?", refreshToken);
// token refresh 요청
return await axios
.post(process.env.REACT_APP_BASE_URL + "/auth/token", {
reAuthorization: `${refreshToken}`,
})
.then((res) => {
// console.log("3. 액세스", res);
//토큰 리프레시 후 액세스토큰을 서버에서 준다면? 어디에 담아두는 지 찾아서 조건문에 넣어두기
if (res.data.access_token) {
// console.log("4. 재발급 토큰", res.data.access_token);
// access token이 재발급 된 상태,
sessionStorage.setItem("accessToken", res.data.access_token);
originalRequest.headers.Authorization = `${res.data.access_token}`;
// console.log('original : ', originalRequest)
return axios(originalRequest);
}
})
.catch((err) => {
const [alertModal, setAlertModal] = useState(false);
const [alertData, setAlertData] = useState("");
// console.log("3. 리프레시만료", err);
//리프레시 토큰이 만료됐다면?
if (err.response.data.message === "Refresh token is not valid") {
sessionStorage.removeItem("userName");
sessionStorage.removeItem("userId");
sessionStorage.removeItem("email");
sessionStorage.removeItem("refreshToken");
sessionStorage.removeItem("accessToken");
Swal.fire({
title: "재로그인이 필요합니다.",
text: "로그인 시간이 만료되었습니다.",
icon: "warning",
confirmButtonColor: "#616AC5",
confirmButtonText: "재로그인하기",
}).then((result) => {
if (result.isConfirmed) {
window.location.href = process.env.REACT_APP_FRONT_URL + `/login`;
}
});
}
});
}
}
);
로직파일에서 import해서 활용한 코드는 아래와 같다.
import { api } from "#utils/Api";
...
const api호출함수 = () => {
api
.method(`url`)
.then((res) => {
// console.log("성공응답?: ", res.data);
})
.catch((err) => {
// console.log('실패응답:', err)
});
};
보통 리프레시 토큰으로 토큰 리프레시 작동 방법에는 2가지가 있다.
1. 매번 access token과 refresh token 을 같이 보낸다.
2. access token으로 api를 호출하고 토큰 만료 오류가 온다면 그때 refresh token을 보낸다.
나는 이 두가지 방법 중 2번을 채택하여 활용한 방법이고 요즘은 불필요한 api 호출을 줄이기 위해 1번을 더 많이 사용한다고 한다.
'react' 카테고리의 다른 글
리코일 (0) | 2023.03.27 |
---|---|
리액트 쿼리 (0) | 2023.03.27 |
emotion과 styled-components (0) | 2023.03.26 |
craco란? (0) | 2022.12.16 |
사진 다운로드 기능 (0) | 2022.12.13 |