瀏覽代碼

update token with gld user within 240min and non gld user within 60

master
Alex Cheung 1 年之前
父節點
當前提交
0722e69040
共有 5 個文件被更改,包括 183 次插入52 次删除
  1. +63
    -26
      src/auth/index.js
  2. +38
    -21
      src/components/AutoLogoutProvider.js
  3. +72
    -0
      src/components/RefreshTokenProvider.js
  4. +8
    -5
      src/index.js
  5. +2
    -0
      src/utils/ApiPathConst.js

+ 63
- 26
src/auth/index.js 查看文件

@@ -12,6 +12,7 @@ export const predictUsageCount = 'predictUsageCount'
export const windowCount = 'windowCount'
import {useNavigate} from "react-router-dom";
import {useDispatch} from "react-redux";
import { REFRESH_TOKEN } from 'utils/ApiPathConst';

// ** Handle User Login
export const handleLogin = data => {
@@ -104,6 +105,8 @@ export const SetupAxiosInterceptors = () => {
const navigate = useNavigate()
const dispatch = useDispatch();
//const updateLastRequestTime = useContext(TimerContext);
let isRefreshToken= false;
axios.interceptors.request.use(
config => {
// ** Get token from localStorage
@@ -126,39 +129,73 @@ export const SetupAxiosInterceptors = () => {
//updateLastRequestTime(Date.now());
return response;
},
error => {
async (error) => {
// ** const { config, response: { status } } = error
const {response} = error
if (error.response.status === 401) {
if (localStorage.getItem("expiredAlertShown") === null) {
localStorage.setItem("expiredAlertShown", true)
alert("登入驗證已過期,請重新登入。")
if (error.response.status === 401 && error.config.url !== apiPath + REFRESH_TOKEN) {
// Make a request to refresh the access token
const refreshToken = localStorage.getItem('refreshToken');
if (isRefreshToken) {
return;
}
}

// ** if (status === 401) {
if (response.status === 401) {
if (localStorage.getItem("expiredAlertShown") === null) {
localStorage.setItem("expiredAlertShown", true)
alert("登入驗證已過期,請重新登入。")
isRefreshToken = true;
return axios
.post(`${apiPath}${REFRESH_TOKEN}`, {
refreshToken: refreshToken // Replace with your refresh token
})
.then((response) => {
if (response.status === 200) {
const newAccessToken = response.data.accessToken;
const newRefreshToken = response.data.refreshToken;
localStorage.setItem('accessToken', newAccessToken);
localStorage.setItem('refreshToken', newRefreshToken);
isRefreshToken = false;
window.location.reload();
}
})
.catch((refreshError) => {
dispatch(handleLogoutFunction());
navigate('/login');
isRefreshToken = false;
window.location.reload();
throw refreshError;
});
} else {
// if (error.response.status === 401) {
// await dispatch(handleLogoutFunction());
// await navigate('/login');
// await window.location.reload();
// }
if (error.response.status === 401) {
if (localStorage.getItem("expiredAlertShown") === null) {
localStorage.setItem("expiredAlertShown", true)
alert("登入驗證已過期,請重新登入。")
}
}
}

if (response && response.status === 401) {
if (localStorage.getItem("expiredAlertShown") === null) {
localStorage.setItem("expiredAlertShown", true)
alert("登入驗證已過期,請重新登入。")
// ** if (status === 401) {
if (response.status === 401) {
if (localStorage.getItem("expiredAlertShown") === null) {
localStorage.setItem("expiredAlertShown", true)
alert("登入驗證已過期,請重新登入。")
}
}
if (response && response.status === 401) {
if (localStorage.getItem("expiredAlertShown") === null) {
localStorage.setItem("expiredAlertShown", true)
alert("登入驗證已過期,請重新登入。")
}
}
if (localStorage.getItem("expiredAlertShown")) {
dispatch(handleLogoutFunction());
navigate('/login');
}
}

if (localStorage.getItem("expiredAlertShown")) {
dispatch(handleLogoutFunction());
navigate('/login');
}

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

+ 38
- 21
src/components/AutoLogoutProvider.js 查看文件

@@ -1,17 +1,29 @@
import React, { createContext, useState, useEffect } from 'react';
//import {useNavigate} from "react-router-dom";
import {useNavigate} from "react-router-dom";
//import axios from "axios";
import {getUserData} from "../auth/utils";
import {isObjEmpty} from "../utils/Utils";
import {useIdleTimer} from "react-idle-timer";
import { handleLogoutFunction } from 'auth/index';
import { useDispatch } from "react-redux";
import {
isUserLoggedIn,
isGLDLoggedIn,
// isPrimaryLoggedIn,
// isCreditorLoggedIn,
// isINDLoggedIn,
// isORGLoggedIn,
// getUserId
} from "utils/Utils";

const TimerContext = createContext();

const AutoLogoutProvider = ({ children }) => {
const [lastRequestTime, setLastRequestTime] = useState(Date.now());
//const navigate = useNavigate();
const [logoutInterval /*, setLogoutInterval*/] = useState(1);
const navigate = useNavigate();
const [logoutInterval, setLogoutInterval] = useState(1);
const [state, setState] = useState('Active');
const dispatch = useDispatch()

const onIdle = () => {
setLastRequestTime(Date.now());
@@ -30,7 +42,7 @@ const AutoLogoutProvider = ({ children }) => {
} = useIdleTimer({
onIdle,
onActive,
timeout: 10_000,
timeout: 1_000,
throttle: 500,
crossTab: true,
syncTimers: 200,
@@ -43,19 +55,23 @@ const AutoLogoutProvider = ({ children }) => {
const userData = getUserData();
if(!isObjEmpty(userData)){
//TODO: get auto logout time here

if(isGLDLoggedIn()){
setLogoutInterval(240);
}else{
setLogoutInterval(1);
}
// axios.get(`${apiPath}${GET_IDLE_LOGOUT_TIME}`,
// )
// .then((response) => {
// if (response.status === 200) {
// setLastRequestTime(Date.now());
// setLogoutInterval(parseInt(response.data.data));
// }
// })
// .catch(error => {
// console.log(error);
// return false;
// });
// .then((response) => {
// if (response.status === 200) {
// setLastRequestTime(Date.now());
// setLogoutInterval(parseInt(response.data.data));
// }
// })
// .catch(error => {
// console.log(error);
// return false;
// });
}
else{
//navigate('/login');
@@ -68,13 +84,14 @@ const AutoLogoutProvider = ({ children }) => {
getRemainingTime();
if(state !== "Active" && lastActiveTab){
const timeElapsed = currentTime - lastRequestTime;
// console.log(timeElapsed);
// console.log(parseInt(timeElapsed/1000));
// console.log(logoutInterval* 60);
if (timeElapsed >= logoutInterval * 60 * 1000) {
//TODO: auto logout here
// console.log("logout");
//await dispatch(handleLogoutFunction());
//await navigate('/login');
//await window.location.reload();
if(isUserLoggedIn()){
alert("登入驗證已過期,請重新登入。")
dispatch(handleLogoutFunction());
navigate('/login');
}
}
}
else if(state === "Active"){


+ 72
- 0
src/components/RefreshTokenProvider.js 查看文件

@@ -0,0 +1,72 @@
import { createContext, useEffect, useRef, useCallback } from 'react';
import { apiPath } from 'auth/utils';
import { REFRESH_TOKEN } from 'utils/ApiPathConst';
import axios from 'axios';

const RefreshTokenContext = createContext();

const RefreshTokenProvider = ({ children }) => {
const token = useRef(localStorage.getItem('accessToken'));
const isRefresh = useRef(false);

// handle Refresh Token Logic
const handleRefreshToken = useCallback(() => {
if (!isRefresh.current) {
const refreshToken = localStorage.getItem('refreshToken');
isRefresh.current = true;
axios
.post(`${apiPath}${REFRESH_TOKEN}`, {
refreshToken: refreshToken
})
.then((response) => {
if (response.status === 200) {
const newAccessToken = response.data.accessToken;
const newRefreshToken = response.data.refreshToken;
localStorage.setItem('accessToken', newAccessToken);
localStorage.setItem('refreshToken', newRefreshToken);
token.current = newAccessToken;
isRefresh.current = false;
} else {
token.current = null;
isRefresh.current = false;
}
})
.catch((refreshError) => {
console.log('Failed to refresh token');
console.log(refreshError)
token.current = null
isRefresh.current = false;
});
}
}, []);

// Function to check token expiry
const checkTokenExpiry = useCallback(() => {
// Check if token is present and its expiry time
if (token.current) {
const tokenExp = JSON.parse(atob(token.current.split('.')[1])).exp;
const currentTime = Math.floor(Date.now() / 1000);
const expiryTime = tokenExp - 30; // Refresh 30 seconds before expiry
// console.log("check refresh Token");
// console.log(currentTime);
// console.log(new Date(currentTime*1000).toLocaleString());
// console.log(expiryTime);
// console.log(new Date(expiryTime*1000).toLocaleString());
// console.log('accessToken: ' + localStorage.getItem('accessToken'));
// console.log('refreshToken: ' + localStorage.getItem('refreshToken'));
if (currentTime >= expiryTime) {
handleRefreshToken();
}
}
}, [token]);

// Start the timer on component mount
useEffect(() => {
const timer = setInterval(checkTokenExpiry, 10000); // Check every 10 second
return () => clearInterval(timer); // Cleanup timer on unmount
}, [checkTokenExpiry]);

return <RefreshTokenContext.Provider value={{}}>{children}</RefreshTokenContext.Provider>;
};

export { RefreshTokenContext, RefreshTokenProvider };

+ 8
- 5
src/index.js 查看文件

@@ -18,6 +18,7 @@ import { store } from 'store';
import reportWebVitals from './reportWebVitals';
import {I18nProvider} from "./components/I18nProvider";
import {AutoLogoutProvider} from "./components/AutoLogoutProvider";
import {RefreshTokenProvider} from "./components/RefreshTokenProvider";

// ==============================|| MAIN - REACT DOM RENDER ||============================== //

@@ -29,11 +30,13 @@ root.render(
<StrictMode>
<ReduxProvider store={store}>
<I18nProvider>
<BrowserRouter basename="/">
<AutoLogoutProvider>
<App />
</AutoLogoutProvider>
</BrowserRouter>
<BrowserRouter basename="/">
<RefreshTokenProvider>
<AutoLogoutProvider>
<App />
</AutoLogoutProvider>
</RefreshTokenProvider>
</BrowserRouter>
</I18nProvider>
</ReduxProvider>
</StrictMode>


+ 2
- 0
src/utils/ApiPathConst.js 查看文件

@@ -1,6 +1,8 @@
import {apiPath} from "../auth/utils";

// GET request
export const REFRESH_TOKEN = "/refresh-token"
export const CHANGE_PASSWORD_PATH = "/user/change-password"

//Group Config
export const GET_GROUP_LIST_PATH = '/group';


Loading…
取消
儲存