Skip to content

Commit

Permalink
Merge pull request #56 from CoolPeace-yanolza/feature/#52
Browse files Browse the repository at this point in the history
[#52] axios interceptor 추가
  • Loading branch information
JitHoon authored Jan 19, 2024
2 parents 6db7ef7 + 6025e95 commit e435883
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 40 deletions.
1 change: 1 addition & 0 deletions src/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default as instance } from './lib/instance';
export { default as getExample } from './lib/getExample';
export { default as postLogin } from './lib/postLogin';
export { default as postRefreshToken } from './lib/postRefreshToken';
80 changes: 66 additions & 14 deletions src/api/lib/instance.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { getCookies } from '@utils/lib/cookies';
import axios from 'axios';
import axios, {
AxiosError,
AxiosResponse,
InternalAxiosRequestConfig
} from 'axios';

import { getCookies, setCookies } from '@utils/lib/cookies';
import { postRefreshToken } from '..';
import { AxiosResponseError } from '@/types/axios';

const instance = axios.create({
baseURL: import.meta.env.VITE_SERVER_URL,
Expand All @@ -8,23 +15,68 @@ const instance = axios.create({
}
});

// 요청 인터셉터 추가
instance.interceptors.request.use(
(config: any): any => {
const accessToken = getCookies('accessToken');
const onRequest = (
config: InternalAxiosRequestConfig
): InternalAxiosRequestConfig => {
const accessToken = getCookies('accessToken');

if (accessToken) {
config.headers['Authorization'] = `Bearer ${accessToken}`;
}

return config;
};

const onErrorRequest = (error: AxiosError | Error): Promise<AxiosError> => {
return Promise.reject(error);
};

const onResponse = (response: AxiosResponse): AxiosResponse => {
return response;
};

const onErrorResponse = async (error: AxiosResponseError<string>) => {
const { config, response } = error;

if (accessToken) {
config.headers['Authorization'] = `Bearer ${accessToken}`;
// 액세스 토큰이 만료되었을 때
if (response && response.status === 401) {
if (error.response.data.code === 'JWT_EXPIRED_AUTHORIZATION') {
const originalRequest = config;

// 토큰 리프레시 요청
const tokenResponse = await postRefreshToken();

// 새로운 토큰 저장
if (tokenResponse.status === 200) {
const {
access_token: newAccessToken,
refresh_token: newRefreshToken,
expires_in: expiresIn
} = tokenResponse.data;
setCookies('accessToken', newAccessToken, expiresIn);
setCookies('refreshToken', newRefreshToken, expiresIn);

// 401로 요청 실패했던 요청 새로운 accessToken으로 재요청
originalRequest.headers['Authorization'] = `Bearer ${newAccessToken}`;
return instance(originalRequest);

// 리프레시 토큰도 만료되었을 때 = 재로그인 안내
} else if (tokenResponse.status === 404) {
console.log(tokenResponse.data.message);
return Promise.reject(error);
}
}
},
error => {
console.log(error.response.data.code, error.response);
return Promise.reject(error);
}
);
console.log('response error : ', error);
return Promise.reject(error);
};

// 요청 인터셉터 추가
instance.interceptors.request.use(onRequest, onErrorRequest);

// TODO : 응답 인터셉터 추가
instance.interceptors.response.use((response: any): any => {
return response;
});
instance.interceptors.response.use(onResponse, onErrorResponse);

export default instance;
14 changes: 14 additions & 0 deletions src/api/lib/postRefreshToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { getCookies } from '@utils/lib/cookies';
import { instance } from '..';

const postRefreshToken = async () => {
const refreshToken = getCookies('refreshToken');

const response = await instance.post('/v1/member/refresh', {
refresh_token: refreshToken
});

return response;
};

export default postRefreshToken;
15 changes: 6 additions & 9 deletions src/components/Login/LoginForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ const LoginForm = () => {

// HACK : 추후 useState로 입력 데이터 관리할 예쩡
const formData: LoginData = {
email: 'mary0393@naver.com',
password: 'qqqq1111!'
email: 'juhwanTest@gmail.com',
password: 'juhwanTest'
};

// HACK: 유효성 검사 기능 구현 후 유효성 메세지 노출 여부 결정
Expand All @@ -33,13 +33,10 @@ const LoginForm = () => {
) => {
event.preventDefault();
const response = await postLogin(formData);
setCookies(
response.name,
response.email,
response.access_token,
response.refresh_token,
response.expires_in
);
setCookies('userName', response.name, response.expires_in);
setCookies('userEmail', response.email, response.expires_in);
setCookies('accessToken', response.access_token, response.expires_in);
setCookies('refreshToken', response.refresh_token, response.expires_in);
};

return (
Expand Down
6 changes: 2 additions & 4 deletions src/types/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,8 @@ export type LoginData = {
};

export type SetCookies = (
userName: string,
userEmail: string,
accessToken: string,
refreshToken: string,
name: string,
value: string,
expiresIn: number
) => void;

Expand Down
15 changes: 15 additions & 0 deletions src/types/axios.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { AxiosResponse, InternalAxiosRequestConfig } from 'axios';

export type ResponseData<T> = {
code: T;
message: T;
};

export type ResponseError<T> = AxiosResponse<T> & {
data: ResponseData<T>;
};

export type AxiosResponseError<T> = {
config: InternalAxiosRequestConfig;
response: ResponseError<T>;
};
17 changes: 4 additions & 13 deletions src/utils/lib/cookies.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
import { SetCookies, GetCookies } from '@/types/auth';

export const setCookies: SetCookies = (
userName,
userEmail,
accessToken,
refreshToken,
expiresIn
) => {
export const setCookies: SetCookies = (name, value, expiresIn) => {
try {
document.cookie = `userName=${userName};max-age=${expiresIn};path=/;secure`;
document.cookie = `userEmail=${userEmail};max-age=${expiresIn};path=/;secure`;
document.cookie = `accessToken=${accessToken};max-age=${expiresIn};path=/;secure`;
document.cookie = `refreshToken=${refreshToken};max-age=${expiresIn};path=/;secure`;
console.log('쿠키설정 성공');
document.cookie = `${name}=${value};max-age=${expiresIn};path=/;secure`;
console.log(`${name}: 쿠키설정 성공`);
} catch (error) {
console.log(error);
alert('쿠키설정에 실패했습니다.');
alert(`${name}: 쿠키설정에 실패했습니다.`);
}
};

Expand Down

0 comments on commit e435883

Please sign in to comment.