Selaa lähdekoodia

fix login sometime no dialog issue

uat
Jason Chuang 2 päivää sitten
vanhempi
commit
cabf3e40a9
3 muutettua tiedostoa jossa 72 lisäystä ja 24 poistoa
  1. +23
    -3
      src/auth/index.js
  2. +43
    -20
      src/auth/jwt/jwtService.js
  3. +6
    -1
      src/pages/authentication/auth-forms/AuthLoginCustom.js

+ 23
- 3
src/auth/index.js Näytä tiedosto

@@ -20,6 +20,16 @@ let axiosInterceptorsSetup = false;
// In-memory guard so only one 401/logout flow shows the alert (avoids race when multiple 401s or interceptors run)
let expiredAlertShownInMemory = false;

/** Login / public auth endpoints must not trigger token refresh or session-expiry reload. */
const isPublicAuthRequest = (reqUrl) =>
reqUrl.includes('/login') || reqUrl.includes('/ldap-login');

/** Clear stale session-expiry flag so a new login attempt can show its own error dialog. */
export const clearExpiredSessionAlert = () => {
localStorage.removeItem('expiredAlertShown');
expiredAlertShownInMemory = false;
};

// ** Handle User Login
export const handleLogin = data => {
return dispatch => {
@@ -152,6 +162,12 @@ export const SetupAxiosInterceptors = () => {
// const { config, response: { status } } = error
const status = error.response?.status
const reqUrl = error.config?.url || ''

// Let login forms handle their own errors (wrong password, locked account, etc.)
if (isPublicAuthRequest(reqUrl)) {
return Promise.reject(error)
}

// iAM Smart registration: HKID already linked — caller must show /iamsmart/pleaseLogin (not refresh/logout)
if (
status === 401 &&
@@ -160,11 +176,15 @@ export const SetupAxiosInterceptors = () => {
) {
return Promise.reject(error)
}
if (status === 401 && error.config?.url !== apiPath + REFRESH_TOKEN) {
if (
status === 401 &&
!isPublicAuthRequest(reqUrl) &&
error.config?.url !== apiPath + REFRESH_TOKEN
) {
// Make a request to refresh the access token
const refreshToken = localStorage.getItem('refreshToken');
if (isRefreshToken) {
return;
return Promise.reject(error);
}
isRefreshToken = true;
return axios
@@ -217,7 +237,7 @@ export const SetupAxiosInterceptors = () => {
// }
// }
if (localStorage.getItem("expiredAlertShown")) {
if (localStorage.getItem("expiredAlertShown") && !isPublicAuthRequest(reqUrl)) {
await dispatch(handleLogoutFunction());
await navigate('/login');
await window.location.reload();


+ 43
- 20
src/auth/jwt/jwtService.js Näytä tiedosto

@@ -40,29 +40,46 @@ export default class JwtService {
// ** const { config, response: { status } } = error
const {config, response} = error
const originalRequest = config
const reqUrl = config?.url || ''

// ** if (status === 401) {
if (response && response.status === 401) {
const isPublicAuthRequest =
reqUrl.includes('/login') ||
reqUrl.includes('/ldap-login') ||
reqUrl.includes('/refresh-token')
if (isPublicAuthRequest) {
return Promise.reject(error)
}

if (!this.isAlreadyFetchingAccessToken) {
this.isAlreadyFetchingAccessToken = true
this.refreshToken().then(r => {
this.isAlreadyFetchingAccessToken = false

// ** Update accessToken in localStorage
this.setToken(r.data.accessToken)
this.setRefreshToken(r.data.refreshToken)

this.onAccessTokenFetched(r.data.accessToken)
})
this.refreshToken()
.then(r => {
this.isAlreadyFetchingAccessToken = false

// ** Update accessToken in localStorage
this.setToken(r.data.accessToken)
this.setRefreshToken(r.data.refreshToken)

this.onAccessTokenFetched(r.data.accessToken)
})
.catch(refreshError => {
this.isAlreadyFetchingAccessToken = false
this.onAccessTokenFetchFailed(refreshError)
})
}
const retryOriginalRequest = new Promise(resolve => {
this.addSubscriber(accessToken => {
// ** Make sure to assign accessToken according to your response.
// ** Check: https://pixinvent.ticksy.com/ticket/2413870
// ** Change Authorization header
originalRequest.headers.Authorization = `${this.jwtConfig.tokenType} ${accessToken}`
resolve(this.axios(originalRequest))
})
const retryOriginalRequest = new Promise((resolve, reject) => {
this.addSubscriber(
accessToken => {
// ** Make sure to assign accessToken according to your response.
// ** Check: https://pixinvent.ticksy.com/ticket/2413870
// ** Change Authorization header
originalRequest.headers.Authorization = `${this.jwtConfig.tokenType} ${accessToken}`
resolve(axios(originalRequest))
},
reject
)
})
return retryOriginalRequest
}
@@ -72,11 +89,17 @@ export default class JwtService {
}

onAccessTokenFetched(accessToken) {
this.subscribers = this.subscribers.filter(callback => callback(accessToken))
this.subscribers.forEach(({ onSuccess }) => onSuccess(accessToken))
this.subscribers = []
}

onAccessTokenFetchFailed(refreshError) {
this.subscribers.forEach(({ onFailure }) => onFailure(refreshError))
this.subscribers = []
}

addSubscriber(callback) {
this.subscribers.push(callback)
addSubscriber(onSuccess, onFailure) {
this.subscribers.push({ onSuccess, onFailure })
}

getToken() {


+ 6
- 1
src/pages/authentication/auth-forms/AuthLoginCustom.js Näytä tiedosto

@@ -40,7 +40,7 @@ import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons';
// import axios from "axios";

import { useDispatch } from "react-redux";
import { handleLogin } from "auth/index";
import { handleLogin, clearExpiredSessionAlert } from "auth/index";
import useJwt from "auth/jwt/useJwt";
import { FormattedMessage, useIntl } from "react-intl";
import { SysContext } from "components/SysSettingProvider"
@@ -74,6 +74,10 @@ const AuthLoginCustom = () => {
/** Blocks a second login before React re-renders (double-click / rapid taps). */
const loginInFlightRef = useRef(false);

useEffect(() => {
clearExpiredSessionAlert();
}, []);

const handleMouseDownPassword = (event) => {
event.preventDefault();
};
@@ -84,6 +88,7 @@ const AuthLoginCustom = () => {
return;
}
loginInFlightRef.current = true;
clearExpiredSessionAlert();
setOnLogin(true)
useJwt
.login({ username: values.username, password: values.password })


Ladataan…
Peruuta
Tallenna