From cca7f01efdc074090961f4e6c8f3aac8a3bcbe77 Mon Sep 17 00:00:00 2001 From: GF Date: Sun, 10 Oct 2021 14:39:54 +0900 Subject: [PATCH 1/3] =?UTF-8?q?[#72]=20refresh=5Ftoken=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/api.js | 14 ++++++++++++++ src/views/login/index.jsx | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/utils/api.js b/src/utils/api.js index e7b443c..3874b4d 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -75,6 +75,7 @@ axiosInstance.interceptors.request.use( if (token) { config.headers.Authorization = token; } + config.withCredentials = true; return config; }, error => { @@ -125,6 +126,19 @@ export function removeToken() { localStorage.removeItem('token'); } +export function setRefreshToken(refreshToken, options = {}) { + const cookie = `refresh_token=${refreshToken}`; + const optionString = Object.entries(options).map(([key, value]) => ( + value === true ? `${key}` : `${key}=${value}` + )).join(';'); + + document.cookie = `${cookie};${optionString}`; +} + +export function removeRefreshToken() { + setRefreshToken('', { 'max-age': -1 }); +} + export function setUserID(userID) { localStorage.setItem('userID', userID); } diff --git a/src/views/login/index.jsx b/src/views/login/index.jsx index e93e62e..a6795f7 100644 --- a/src/views/login/index.jsx +++ b/src/views/login/index.jsx @@ -6,7 +6,7 @@ import { Button, Box, makeStyles, Container, Typography, Link } from '@material- import Loading from '@components/Loading'; import UosInput from '@components/UosInput'; import { semesterState } from '@states/Semester'; -import { API_LOGIN, API_GET_SEMESTER, requestAPI, getToken, setToken, removeUserID, setUserID } from '@utils/api'; +import { API_LOGIN, API_GET_SEMESTER, requestAPI, getToken, setToken, setRefreshToken, removeUserID, setUserID } from '@utils/api'; import { foregroundColor } from '@utils/styles/Colors'; import useLogoLayoutStyles from '@utils/styles/login/LogoLayout'; import useLoginLabelStyles from '@utils/styles/login/LoginLabel'; @@ -85,6 +85,7 @@ export function LoginBox() { } setToken(response.data.token); + setRefreshToken(response.data.refresh); setUserID(response.data.userId); await callSemester(); getSocket(); From 3752c11e6b8bb905a7b6e0b41c1296578cb547b4 Mon Sep 17 00:00:00 2001 From: GF Date: Sun, 10 Oct 2021 14:40:23 +0900 Subject: [PATCH 2/3] =?UTF-8?q?[#72]=20401=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=8B=9C=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=EB=A1=9C=20=EB=A6=AC=EB=8B=A4=EC=9D=B4=EB=A0=89?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/api.js | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/utils/api.js b/src/utils/api.js index 3874b4d..3f5102e 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -1,6 +1,7 @@ /* eslint-disable no-console */ /* eslint-disable no-unused-vars */ import axios from 'axios'; +import { StatusCodes } from 'http-status-codes'; import usePopup from '@components/usePopup'; const { API_URL_BASE } = process.env; @@ -88,9 +89,27 @@ axiosInstance.interceptors.request.use( axiosInstance.interceptors.response.use( config => config, - error => Promise.resolve(error.response), + error => { + console.error(error.stack); + return Promise.reject(error.response); + }, ); +function handleStatus(error) { + const { status } = error; + + // 401 + if (status === StatusCodes.UNAUTHORIZED) { + // redirect to login page + removeToken(); + removeUserID(); + removeRefreshToken(); + window.location.href = '/login'; + } + + // TODO: Edit here for other status codes +} + export async function requestAPI(config) { try { if (config.needToken && !getToken()) { @@ -106,11 +125,12 @@ export async function requestAPI(config) { // for test console.log(response); - // includes 3xx, 4xx responses + // includes 2xx responses return response; } catch (error) { - console.error(error); - return null; + handleStatus(error); + + return error; } } From 87ea07e1e58836a38848eeb052f0c63cd5798975 Mon Sep 17 00:00:00 2001 From: GF Date: Sun, 10 Oct 2021 15:45:57 +0900 Subject: [PATCH 3/3] =?UTF-8?q?[#72]=20=EB=A7=8C=EB=A3=8C=EB=90=9C=20acces?= =?UTF-8?q?s=5Ftoken=20=EA=B0=B1=EC=8B=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/api.js | 23 ++++++++++++++++------- src/utils/cookie.js | 12 ++++++++++++ 2 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 src/utils/cookie.js diff --git a/src/utils/api.js b/src/utils/api.js index 3f5102e..862d99f 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -3,6 +3,7 @@ import axios from 'axios'; import { StatusCodes } from 'http-status-codes'; import usePopup from '@components/usePopup'; +import { clearCookie, setCookie } from './cookie'; const { API_URL_BASE } = process.env; @@ -110,6 +111,17 @@ function handleStatus(error) { // TODO: Edit here for other status codes } +// if access_token expired, refresh the token +function checkAccessToken() { + // get new token from cookie + const match = document.cookie.match(/(^| )access_token=([^;]+)/); + if (!match) return; + + const token = decodeURIComponent(match[2]); + setToken(token); + clearCookie('access_token'); +} + export async function requestAPI(config) { try { if (config.needToken && !getToken()) { @@ -122,6 +134,8 @@ export async function requestAPI(config) { delete config.needToken; const response = await axiosInstance.request(config); + checkAccessToken(); + // for test console.log(response); @@ -147,16 +161,11 @@ export function removeToken() { } export function setRefreshToken(refreshToken, options = {}) { - const cookie = `refresh_token=${refreshToken}`; - const optionString = Object.entries(options).map(([key, value]) => ( - value === true ? `${key}` : `${key}=${value}` - )).join(';'); - - document.cookie = `${cookie};${optionString}`; + setCookie('refresh_token', refreshToken, options); } export function removeRefreshToken() { - setRefreshToken('', { 'max-age': -1 }); + clearCookie('refresh_token'); } export function setUserID(userID) { diff --git a/src/utils/cookie.js b/src/utils/cookie.js new file mode 100644 index 0000000..eac3d2b --- /dev/null +++ b/src/utils/cookie.js @@ -0,0 +1,12 @@ +export function setCookie(name, value, options = {}) { + const cookie = `${name}=${value}`; + const optionString = Object.entries(options).map(([key, value]) => ( + value === true ? `${key}` : `${key}=${value}` + )).join(';'); + + document.cookie = `${cookie};${optionString}`; +} + +export function clearCookie(name) { + setCookie(name, '', { 'max-age': -1 }); +}