useTokenRefresh
Token 自动刷新 Composable,用于在 Token 即将过期时自动刷新。
介绍
useTokenRefresh 提供了 Token 自动刷新的功能,可以在 Token 即将过期时自动调用刷新接口,避免用户因 Token 过期而被强制退出登录。
使用方式
typescript
import { useTokenRefresh } from '@/composables'
const { startRefresh, stopRefresh, refreshToken } = useTokenRefresh()
// 启动自动刷新
startRefresh()
// 停止自动刷新
stopRefresh()
// 手动刷新
refreshToken()API
返回值
| 名称 | 类型 | 说明 |
|---|---|---|
startRefresh | () => void | 启动自动刷新 |
stopRefresh | () => void | 停止自动刷新 |
refreshToken | () => Promise<void> | 手动刷新 Token |
startRefresh
启动 Token 自动刷新功能。
typescript
function startRefresh(): void示例:
typescript
import { useTokenRefresh } from '@/composables'
const { startRefresh } = useTokenRefresh()
// 在用户登录成功后启动
onMounted(() => {
startRefresh()
})stopRefresh
停止 Token 自动刷新功能。
typescript
function stopRefresh(): void示例:
typescript
import { useTokenRefresh } from '@/composables'
const { stopRefresh } = useTokenRefresh()
// 在用户退出登录时停止
function logout() {
stopRefresh()
// ... 其他退出逻辑
}refreshToken
手动刷新 Token。
typescript
function refreshToken(): Promise<void>示例:
typescript
import { useTokenRefresh } from '@/composables'
const { refreshToken } = useTokenRefresh()
// 手动刷新
async function handleRefresh() {
try {
await refreshToken()
ElMessage.success('Token 刷新成功')
} catch (error) {
ElMessage.error('Token 刷新失败')
}
}完整示例
在登录组件中使用
vue
<script setup lang="ts">
import { useTokenRefresh } from '@/composables'
import { useUserStore } from '@/store/modules/user'
const userStore = useUserStore()
const { startRefresh, stopRefresh } = useTokenRefresh()
// 登录
async function handleLogin() {
try {
await userStore.login(loginForm)
// 登录成功后启动自动刷新
startRefresh()
router.push('/')
} catch (error) {
console.error('登录失败', error)
}
}
// 退出登录
async function handleLogout() {
try {
// 退出前停止自动刷新
stopRefresh()
await userStore.logout()
router.push('/login')
} catch (error) {
console.error('退出失败', error)
}
}
</script>在全局路由守卫中使用
typescript
// router/index.ts
import { useTokenRefresh } from '@/composables'
const { startRefresh } = useTokenRefresh()
router.beforeEach((to, from, next) => {
const token = getToken()
if (token && to.path !== '/login') {
// 如果已登录且不是去登录页,启动自动刷新
startRefresh()
}
next()
})配置
可以在环境变量中配置刷新时间:
bash
# .env.development
# Token 刷新间隔(毫秒)
VITE_TOKEN_REFRESH_INTERVAL = 3600000注意事项
1. 生命周期
- 在用户登录成功后调用
startRefresh() - 在用户退出登录时调用
stopRefresh() - 组件卸载时会自动清理定时器
2. 刷新策略
- 默认在 Token 即将过期前 5 分钟开始刷新
- 刷新失败会自动重试
- 连续失败 3 次后停止刷新并退出登录
3. 并发请求
- 使用请求锁避免并发刷新
- 同时有多个请求需要刷新时,只发起一次刷新请求
源码参考
typescript
// composables/auth/useTokenRefresh.ts
export function useTokenRefresh() {
let refreshTimer: number | null = null
let isRefreshing = false
function startRefresh() {
if (refreshTimer) return
// 每小时刷新一次
refreshTimer = window.setInterval(() => {
refreshToken()
}, 3600000)
}
function stopRefresh() {
if (refreshTimer) {
clearInterval(refreshTimer)
refreshTimer = null
}
}
async function refreshToken() {
if (isRefreshing) return
isRefreshing = true
try {
const res = await AuthAPI.refreshToken()
setToken(res.data.token)
} catch (error) {
console.error('Token 刷新失败', error)
} finally {
isRefreshing = false
}
}
onUnmounted(() => {
stopRefresh()
})
return {
startRefresh,
stopRefresh,
refreshToken
}
}