Skip to content

Commit

Permalink
Merge pull request #145 from Ong-gi-Jong-gi/dev
Browse files Browse the repository at this point in the history
[DEPLOY] 로그인 인증 방식 변경 로직 추가
  • Loading branch information
SangWoo9734 authored Aug 25, 2024
2 parents 40f0cb3 + 0f56e4b commit 113f8b7
Show file tree
Hide file tree
Showing 12 changed files with 102 additions and 53 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,7 @@ dist-ssr
*.sw?

.env
*storybook.log
*storybook.log

# key files
/cert
13 changes: 2 additions & 11 deletions src/apis/auth/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import FACETIME from '../../constants/FACETIME';
import routes from '../../constants/routes';
import { responseRoot } from '../../types/api';
import { LoginValues, UserLoginType } from '../../types/auth';
import { setCookie } from '../../utils/cookie';
import { getExpireTime } from '../../utils/tokenUtils';

const postLogin = async (loginId: string, password: string) => {
try {
Expand Down Expand Up @@ -44,15 +42,8 @@ export const usePostLogin = () => {
mutationFn: ({ userId, password }: LoginValues) =>
postLogin(userId, password),
onSuccess: ({ data, authorization }) => {
const expireTime = getExpireTime(authorization);
const expireDate = new Date();
expireDate.setMinutes(expireDate.getMinutes() + expireTime);

setCookie('authorization', authorization, {
path: '/',
secure: true,
expires: expireDate,
});
// access token 저장
localStorage.setItem('accessKey', authorization);

localStorage.setItem(FACETIME.LOCAL_STORAGE_KEY, data.nickname);

Expand Down
3 changes: 1 addition & 2 deletions src/apis/auth/logout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { useNavigate } from 'react-router-dom';
import { authorizedApi } from '..';
import API from '../../constants/API';
import routes from '../../constants/routes';
import { deleteCookie } from '../../utils/cookie';

export const postLogout = async () => {
const response = await authorizedApi.post(API.AUTH.LOGOUT);
Expand All @@ -17,7 +16,7 @@ export const useLogout = () => {
mutationKey: [API.AUTH.LOGOUT],
mutationFn: () => postLogout(),
onSettled: () => {
deleteCookie('authorization');
localStorage.removeItem('accessKey');
navigate(routes.login, { replace: true });
},
onError: (error) => {
Expand Down
18 changes: 18 additions & 0 deletions src/apis/auth/token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { api } from '..';
import API from '../../constants/API';

export const tokenRefresh = async () => {
const { headers } = await api({
method: 'post',
url: API.AUTH.REFRESH,
withCredentials: true, // 쿠키를 포함시키기 위해 필요
});

const authorization = headers['authorization'];

if (authorization) {
localStorage.setItem('accessKey', authorization);
} else {
throw new Error('Failed to refresh token: no authorization header found.');
}
};
51 changes: 48 additions & 3 deletions src/apis/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
import axios from 'axios';
import { getCookie } from '../utils/cookie';
import { tokenRefresh } from './auth/token';

export const api = axios.create({
baseURL: import.meta.env.VITE_API_URL,
headers: {
'Content-Type': 'application/json',
},
withCredentials: true,
});

api.interceptors.response.use(
(response) => response,
(error) => {
if (error.response.config.url.includes('refresh-token')) {
const errorMessage = error.response?.data?.message || '';

if (errorMessage.includes('No refresh token provided')) {
localStorage.removeItem('accessKey');
window.location.href = '/';
}
}

return Promise.reject(error);
},
);

export const authorizedApi = axios.create({
baseURL: import.meta.env.VITE_API_URL,
headers: {
Expand All @@ -16,7 +33,35 @@ export const authorizedApi = axios.create({
});

authorizedApi.interceptors.request.use((config) => {
const token = `Bearer ${getCookie('authorization')}`;
config.headers.Authorization = token;
const token = `Bearer ${localStorage.getItem('accessKey')}`;
if (token) {
config.headers.Authorization = token;
}
return config;
});

authorizedApi.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config;

if (error.response?.status === 401) {
const errorMessage = error.response?.data?.message || '';

if (errorMessage.includes('Access token is invalid or missing')) {
await tokenRefresh();
const newToken = localStorage.getItem('accessKey');
if (newToken) {
originalRequest.headers.Authorization = `Bearer ${newToken}`;
return authorizedApi(originalRequest); // 재요청
}
}

if (errorMessage.includes('Invalid refresh token')) {
window.location.href = '/login';
}
}

return Promise.reject(error);
},
);
3 changes: 1 addition & 2 deletions src/components/common/layouts/PrivateLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import QueryString from 'qs';
import { Navigate, Outlet } from 'react-router-dom';
import routes from '../../../constants/routes';
import { getCookie } from '../../../utils/cookie';

const PrivateLayout = () => {
const token = getCookie('authorization');
const token = localStorage.getItem('accessKey');

if (!token) {
const queryData = QueryString.parse(location.search, {
Expand Down
1 change: 1 addition & 0 deletions src/constants/API.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const AUTH = {
SIGNUP: '/signup',
LOGIN: '/login',
LOGOUT: '/logout',
REFRESH: '/api/refresh-token',
};

const FAMILY = {
Expand Down
3 changes: 1 addition & 2 deletions src/pages/LoginPage.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { Navigate } from 'react-router-dom';
import LoginForm from '../components/login/LoginForm';
import routes from '../constants/routes';
import { getCookie } from '../utils/cookie';

const LoginPage = () => {
const token = getCookie('authorization');
const token = localStorage.getItem('accessKey');

if (token) return <Navigate to={routes.main} replace />;
return (
Expand Down
3 changes: 1 addition & 2 deletions src/pages/SignupPage.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { Navigate } from 'react-router-dom';
import SignupForm from '../components/signup/SignupForm';
import routes from '../constants/routes';
import { getCookie } from '../utils/cookie';

const SignupPage = () => {
const token = getCookie('authorization');
const token = localStorage.getItem('accessKey');

if (token) return <Navigate to={routes.main} replace />;

Expand Down
15 changes: 0 additions & 15 deletions src/utils/cookie.ts

This file was deleted.

5 changes: 2 additions & 3 deletions src/utils/tokenUtils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import base64 from 'base-64';
import { TokenType } from '../types/token';
import { getCookie } from './cookie';

const parseJwtToken: (arg: string) => TokenType = (jwtToken: string) => {
//jwt토큰 디코딩
Expand All @@ -21,8 +20,8 @@ export const getExpireTime = (token: string) => {
};

export const getUserId = () => {
const jwtToken = getCookie('authorization');
const parsedToken = parseJwtToken(jwtToken);
const jwtToken = localStorage.getItem('accessKey');
const parsedToken = parseJwtToken(jwtToken || '');

return parsedToken.loginId;
};
35 changes: 23 additions & 12 deletions vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
import fs from 'fs';
import path from 'path';
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';

// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
server: {
host: '0.0.0.0',
port: 5173,
},
define: {
global: {},
},
build: {
chunkSizeWarningLimit: 1600,
},
export default defineConfig(({ mode }) => {
return {
plugins: [react()],
server: {
host: '0.0.0.0',
port: 5173,
https:
mode === 'production'
? {}
: {
key: fs.readFileSync(path.resolve('./cert', 'localhost-key.pem')),
cert: fs.readFileSync(path.resolve('./cert', 'localhost.pem')),
},
},
define: {
global: {},
},
build: {
chunkSizeWarningLimit: 1600,
},
};
});

0 comments on commit 113f8b7

Please sign in to comment.