Skip to content

Commit

Permalink
[#2099] fix(web): redirect to login page if token has expired (#2312)
Browse files Browse the repository at this point in the history
### What changes were proposed in this pull request?

Remove refresh token and redirect to login page if token has expired.

### Why are the changes needed?

Fix: #2099 

### Does this PR introduce _any_ user-facing change?

N/A

### How was this patch tested?

N/A
  • Loading branch information
ch3yne authored Feb 29, 2024
1 parent 8726cc5 commit 4ace788
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 50 deletions.
3 changes: 2 additions & 1 deletion web/app/ui/login/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ const LoginPage = () => {

const onSubmit = async data => {
dispatch(loginAction({ params: data, router }))
reset()

reset({ ...data })
}

const onError = errors => {
Expand Down
13 changes: 7 additions & 6 deletions web/lib/api/auth/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
* This software is licensed under the Apache License version 2.
*/

import axios from 'axios'
import { defHttp } from '@/lib/utils/axios'

export const getAuthConfigsApi = () => {
Expand All @@ -13,9 +12,11 @@ export const getAuthConfigsApi = () => {
}

export const loginApi = (url, params) => {
return axios({
url,
method: 'post',
params
})
return defHttp.post(
{
url,
params
},
{ withToken: false }
)
}
15 changes: 11 additions & 4 deletions web/lib/layout/Logout.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,27 @@

'use client'

import { useRouter } from 'next/navigation'

import { Box, IconButton } from '@mui/material'

import Icon from '@/components/Icon'
import { useAuth } from '../provider/session'
import { useAppSelector } from '../hooks/useStore'
import { useAppDispatch, useAppSelector } from '../hooks/useStore'
import { logoutAction } from '../store/auth'

const LogoutButton = () => {
const auth = useAuth()
const router = useRouter()
const dispatch = useAppDispatch()
const authStore = useAppSelector(state => state.auth)

const handleLogout = () => {
dispatch(logoutAction({ router }))
}

return (
<Box>
{authStore.authToken ? (
<IconButton onClick={() => auth.logout()}>
<IconButton onClick={() => handleLogout()}>
<Icon icon={'bx:exit'} />
</IconButton>
) : null}
Expand Down
30 changes: 5 additions & 25 deletions web/lib/provider/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,16 @@ import { createContext, useEffect, useState, useContext } from 'react'

import { useRouter } from 'next/navigation'

import { useAppDispatch, useAppSelector } from '@/lib/hooks/useStore'
import { initialVersion, setVersion as setStoreVersion } from '@/lib/store/sys'
import { useAppDispatch } from '@/lib/hooks/useStore'
import { initialVersion } from '@/lib/store/sys'

import { to } from '../utils'
import { getAuthConfigs, setAuthToken, setIntervalId, loginAction } from '../store/auth'
import { getAuthConfigs, setAuthToken } from '../store/auth'

const authProvider = {
version: '',
loading: true,
setLoading: () => Boolean,
login: () => Promise.resolve(),
logout: () => Promise.resolve()
setLoading: () => Boolean
}

const AuthContext = createContext(authProvider)
Expand All @@ -34,23 +32,8 @@ const AuthProvider = ({ children }) => {
const token = (typeof window !== 'undefined' && localStorage.getItem('accessToken')) || null
const version = (typeof window !== 'undefined' && localStorage.getItem('version')) || null

const authStore = useAppSelector(state => state.auth)
const dispatch = useAppDispatch()

const handleLogin = async params => {
dispatch(loginAction({ params, router }))
}

const handleLogout = () => {
localStorage.removeItem('version')
localStorage.removeItem('accessToken')
localStorage.removeItem('authParams')

dispatch(setStoreVersion(''))
dispatch(setAuthToken(''))
router.push('/ui/login')
}

useEffect(() => {
const initAuth = async () => {
const [authConfigsErr, resAuthConfigs] = await to(dispatch(getAuthConfigs()))
Expand All @@ -60,7 +43,6 @@ const AuthProvider = ({ children }) => {
dispatch(initialVersion())
} else if (authType === 'oauth') {
if (token) {
dispatch(setIntervalId())
dispatch(setAuthToken(token))
dispatch(initialVersion())
} else {
Expand All @@ -76,9 +58,7 @@ const AuthProvider = ({ children }) => {
const values = {
version,
token,
loading,
login: handleLogin,
logout: handleLogout
loading
}

return <AuthContext.Provider value={values}>{children}</AuthContext.Provider>
Expand Down
22 changes: 17 additions & 5 deletions web/lib/store/auth/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@ export const getAuthConfigs = createAsyncThunk('auth/getAuthConfigs', async () =
let authType = null
const [err, res] = await to(getAuthConfigsApi())

if (!err && res) {
oauthUrl = `${res['gravitino.authenticator.oauth.serverUri']}${res['gravitino.authenticator.oauth.tokenPath']}`

authType = res['gravitino.authenticator']
if (err || !res) {
throw new Error(err)
}

oauthUrl = `${res['gravitino.authenticator.oauth.serverUri']}${res['gravitino.authenticator.oauth.tokenPath']}`
authType = res['gravitino.authenticator']

localStorage.setItem('oauthUrl', oauthUrl)

return { oauthUrl, authType }
})

Expand Down Expand Up @@ -58,7 +61,7 @@ export const loginAction = createAsyncThunk('auth/loginAction', async ({ params,
throw new Error(err)
}

const { access_token, expires_in } = res?.data
const { access_token, expires_in } = res

localStorage.setItem('accessToken', access_token)
localStorage.setItem('expiredIn', expires_in)
Expand All @@ -72,6 +75,15 @@ export const loginAction = createAsyncThunk('auth/loginAction', async ({ params,
return { token: access_token, expired: expires_in }
})

export const logoutAction = createAsyncThunk('auth/logoutAction', async ({ router }, { getState, dispatch }) => {
localStorage.removeItem('accessToken')
localStorage.removeItem('authParams')
dispatch(setAuthToken(''))
await router.push('/ui/login')

return { token: null }
})

export const setIntervalId = createAsyncThunk('auth/setIntervalId', async (expiredIn, { dispatch }) => {
const localExpiredIn = localStorage.getItem('expiredIn')

Expand Down
6 changes: 3 additions & 3 deletions web/lib/utils/axios/checkStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ SOFTWARE.

import type { ErrorMessageMode } from '@/types/axios'
import toast from 'react-hot-toast'
import { useRouter as Router } from 'next/navigation'

export function checkStatus(status: number, msg: string, errorMessageMode: ErrorMessageMode = 'message'): void {
let errMessage = ''
Expand All @@ -39,12 +38,13 @@ export function checkStatus(status: number, msg: string, errorMessageMode: Error
break

case 401:
// ** reserve error message
errMessage = msg || 'The user does not have permission (token, user name, password error or expired)!'

localStorage.removeItem('accessToken')
localStorage.removeItem('version')
localStorage.removeItem('authParams')

Router().push('/ui/login')
window.location.href = '/ui/login'

break
case 403:
Expand Down
12 changes: 6 additions & 6 deletions web/lib/utils/axios/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ const transform: AxiosTransform = {
config.params = params
} else {
// ** If no data is provided for non-GET requests, the params will be treated as data
config.data = params
config.params = undefined
// config.data = params
// config.params = undefined
}
if (joinParamsToUrl) {
config.url = setObjToUrlParams(config.url as string, Object.assign({}, config.params, config.data))
Expand Down Expand Up @@ -190,8 +190,8 @@ const transform: AxiosTransform = {
* @description: Error Response Handling
*/
responseInterceptorsCatch: (axiosInstance: AxiosInstance, error: any) => {
const { response, code, message, config } = error || {}
const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none'
const { response, code, message, config: originConfig } = error || {}
const errorMessageMode = originConfig?.requestOptions?.errorMessageMode || 'none'
const msg: string = response?.data?.error?.message ?? response?.data?.message ?? ''
const err: string = error?.toString?.() ?? ''
let errMessage = ''
Expand Down Expand Up @@ -224,8 +224,8 @@ const transform: AxiosTransform = {
checkStatus(error?.response?.status, msg, errorMessageMode)

const retryRequest = new AxiosRetry()
const { isOpenRetry } = config.requestOptions.retryRequest
config.method?.toUpperCase() === RequestEnum.GET && isOpenRetry && retryRequest.retry(axiosInstance, error)
const { isOpenRetry } = originConfig.requestOptions.retryRequest
originConfig.method?.toUpperCase() === RequestEnum.GET && isOpenRetry && retryRequest.retry(axiosInstance, error)

return Promise.reject(error)
}
Expand Down

0 comments on commit 4ace788

Please sign in to comment.