diff --git a/package-lock.json b/package-lock.json index b550f30f..c009455f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@emotion/styled": "^11.9.3", "@tanstack/react-query": "^4.0.10", "axios": "^0.27.2", + "moment": "^2.29.4", "next": "12.2.2", "react": "18.2.0", "react-cookie": "^4.1.1", @@ -3736,6 +3737,14 @@ "dev": true, "license": "MIT" }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "engines": { + "node": "*" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -7675,6 +7684,11 @@ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, + "moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", diff --git a/package.json b/package.json index cf4c265a..6b46b2c1 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "@emotion/styled": "^11.9.3", "@tanstack/react-query": "^4.0.10", "axios": "^0.27.2", + "moment": "^2.29.4", "next": "12.2.2", "react": "18.2.0", "react-cookie": "^4.1.1", diff --git a/src/components/Layout/Header.tsx b/src/components/Layout/Header.tsx index bbcef950..8aaf3f4f 100644 --- a/src/components/Layout/Header.tsx +++ b/src/components/Layout/Header.tsx @@ -5,7 +5,7 @@ import { FiLogIn, FiUser } from 'react-icons/fi' import Link from 'next/link' import { useEffect, useState, useCallback } from 'react' import { MYINFO_URL, LOGIN_URL, USER_URL, HOME_URL } from '@constants/pageUrl' -import { getLocalToken } from '@utils/localToken' +import { getToken } from '@utils/cookie' const MYINFO = '내정보' const USER = '메뉴판' @@ -22,7 +22,7 @@ export const Header = () => { useEffect(() => { if (pathname === LOGIN_URL || pathname === HOME_URL) { - setToken(getLocalToken() || '') + setToken(getToken() || '') } }, [token, pathname]) diff --git a/src/lib/axios/interceptors.ts b/src/lib/axios/interceptors.ts index a184dfd4..e79f742d 100644 --- a/src/lib/axios/interceptors.ts +++ b/src/lib/axios/interceptors.ts @@ -1,17 +1,8 @@ import { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios' -import { getToken } from '@utils/cookie' +import { checkToken } from '@utils/checkToken' -export const handleRequest = ( - config: AxiosRequestConfig -): AxiosRequestConfig => { - const token = getToken() - if (!config?.headers) { - throw new Error(`Axios config headers must be provided`) - } - if (token) { - config.headers.Authorization = token - } - return config +export const handleRequest = async (config: AxiosRequestConfig) => { + return checkToken(config) } export const handleRequestError = (error: AxiosError): Promise => { diff --git a/src/utils/checkToken.ts b/src/utils/checkToken.ts new file mode 100644 index 00000000..f11b85d7 --- /dev/null +++ b/src/utils/checkToken.ts @@ -0,0 +1,32 @@ +import { AxiosRequestConfig } from 'axios' +import { getTokenData, setToken } from '@utils/cookie' +import moment from 'moment' +import axios from 'axios' + +export const checkToken = async (config: AxiosRequestConfig) => { + const { currentUser, tastyToken, tastyToken_expire, tastyRefreshToken } = + getTokenData() + + if (!config?.headers) { + throw new Error(`Axios config headers must be provided`) + } + + if ( + moment(tastyToken_expire).diff(moment(), 'minutes') < 10 && + tastyRefreshToken + ) { + const { data } = await axios.post( + `${process.env.NEXT_PUBLIC_API_URL}/re-issue`, + { + email: currentUser.email, + accessToken: tastyToken, + refreshToken: tastyRefreshToken + } + ) + setToken(data) + config.headers.Authorization = data.token + } else { + config.headers.Authorization = tastyToken + } + return config +} diff --git a/src/utils/cookie.ts b/src/utils/cookie.ts index bb953b00..4a9c36f3 100644 --- a/src/utils/cookie.ts +++ b/src/utils/cookie.ts @@ -34,8 +34,14 @@ export const removeCookie = (name: string) => { } export const setToken = ({ token, expirationDate }: Token) => { - setCookie(TOKEN_KEY, token) - setCookie(TOKEN_EXPIRE_DATE, expirationDate) + setCookie(TOKEN_KEY, token, { + path: '/', + expires: new Date(expirationDate) + }) + setCookie(TOKEN_EXPIRE_DATE, expirationDate, { + path: '/', + expires: new Date(expirationDate) + }) } export const getToken = () => { @@ -55,18 +61,23 @@ export const getTokenData = () => { export const setTokenData = ({ accessToken, account, refreshToken }: Data) => { setCookie(TOKEN_KEY, accessToken.token, { + path: '/', expires: new Date(accessToken.expirationDate) }) setCookie(TOKEN_EXPIRE_DATE, accessToken.expirationDate, { + path: '/', expires: new Date(accessToken.expirationDate) }) setCookie(REFRESH_TOKEN_KEY, refreshToken.token, { + path: '/', expires: new Date(refreshToken.expirationDate) }) setCookie(REFRESH_TOKEN_EXPIRE_DATE, refreshToken.expirationDate, { + path: '/', expires: new Date(refreshToken.expirationDate) }) setCookie(CURRENT_USER, JSON.stringify(account), { + path: '/', expires: new Date(accessToken.expirationDate) }) }