Skip to content

Commit 40c5e6d

Browse files
authored
fix: Page may lock if user close the page when refresh access_token (#10550)
1 parent e4d1757 commit 40c5e6d

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

web/service/refresh-token.ts

+15-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import { apiPrefix } from '@/config'
22
import { fetchWithRetry } from '@/utils'
33

4+
const LOCAL_STORAGE_KEY = 'is_other_tab_refreshing'
5+
46
let isRefreshing = false
57
function waitUntilTokenRefreshed() {
68
return new Promise<void>((resolve, reject) => {
79
function _check() {
8-
const isRefreshingSign = localStorage.getItem('is_refreshing')
10+
const isRefreshingSign = globalThis.localStorage.getItem(LOCAL_STORAGE_KEY)
911
if ((isRefreshingSign && isRefreshingSign === '1') || isRefreshing) {
1012
setTimeout(() => {
1113
_check()
@@ -22,13 +24,14 @@ function waitUntilTokenRefreshed() {
2224
// only one request can send
2325
async function getNewAccessToken(): Promise<void> {
2426
try {
25-
const isRefreshingSign = localStorage.getItem('is_refreshing')
27+
const isRefreshingSign = globalThis.localStorage.getItem(LOCAL_STORAGE_KEY)
2628
if ((isRefreshingSign && isRefreshingSign === '1') || isRefreshing) {
2729
await waitUntilTokenRefreshed()
2830
}
2931
else {
30-
globalThis.localStorage.setItem('is_refreshing', '1')
3132
isRefreshing = true
33+
globalThis.localStorage.setItem(LOCAL_STORAGE_KEY, '1')
34+
globalThis.addEventListener('beforeunload', releaseRefreshLock)
3235
const refresh_token = globalThis.localStorage.getItem('refresh_token')
3336

3437
// Do not use baseFetch to refresh tokens.
@@ -61,15 +64,21 @@ async function getNewAccessToken(): Promise<void> {
6164
return Promise.reject(error)
6265
}
6366
finally {
67+
releaseRefreshLock()
68+
}
69+
}
70+
71+
function releaseRefreshLock() {
72+
if (isRefreshing) {
6473
isRefreshing = false
65-
globalThis.localStorage.removeItem('is_refreshing')
74+
globalThis.localStorage.removeItem(LOCAL_STORAGE_KEY)
75+
globalThis.removeEventListener('beforeunload', releaseRefreshLock)
6676
}
6777
}
6878

6979
export async function refreshAccessTokenOrRelogin(timeout: number) {
7080
return Promise.race([new Promise<void>((resolve, reject) => setTimeout(() => {
71-
isRefreshing = false
72-
globalThis.localStorage.removeItem('is_refreshing')
81+
releaseRefreshLock()
7382
reject(new Error('request timeout'))
7483
}, timeout)), getNewAccessToken()])
7584
}

0 commit comments

Comments
 (0)