React+Django REST Framework中JWT过期后用户未自动登出问题
JWT令牌过期后前端未自动登出的解决方案
问题根源
你当前仅在登录时存储JWT令牌,但未实现令牌过期监听和API请求错误拦截,导致access token过期后前端无法感知并触发登出逻辑。
具体解决步骤
1. 登录时设置过期定时器,主动触发登出
登录解析access token的过期时间,设置定时器,到期后自动清除令牌并跳转登录页:
let loginUser = async (e )=> { e.preventDefault() try { const res = await axios.post('http://127.0.0.1:8000/api/token/', { headers: { 'Content-type': 'application/json' }, username: e.target.username.value, password: e.target.password.value }) const authTokens = res.data setAuthTokens(authTokens) const userData = jwt_decode(authTokens.access) setUser(userData) localStorage.setItem('authTokens', JSON.stringify(authTokens)) // 计算过期剩余时间,设置自动登出定时器 const expiresIn = userData.exp * 1000 - Date.now() setTimeout(() => { localStorage.removeItem('authTokens') setAuthTokens(null) setUser(null) navigate('/login') }, expiresIn) navigate('/') } catch { alert('登录失败,请检查账号密码') } }
2. 全局拦截API请求,处理401错误
用axios拦截器统一捕获401响应(令牌过期/无效),避免页面刷新后定时器丢失导致的漏判:
// 在axios初始化文件或App组件中添加拦截器 axios.interceptors.response.use( response => response, error => { if (error.response?.status === 401) { // 清除令牌并强制跳转登录页 localStorage.removeItem('authTokens') window.location.href = '/login' } return Promise.reject(error) } )
3. 页面刷新时重新初始化定时器
页面刷新后之前的定时器会消失,需在应用初始化时检查本地存储的令牌状态:
useEffect(() => { const storedTokens = localStorage.getItem('authTokens') if (storedTokens) { const authTokens = JSON.parse(storedTokens) const userData = jwt_decode(authTokens.access) const expiresIn = userData.exp * 1000 - Date.now() if (expiresIn > 0) { // 令牌未过期,重新设置定时器 setTimeout(() => { localStorage.removeItem('authTokens') setAuthTokens(null) setUser(null) navigate('/login') }, expiresIn) } else { // 令牌已过期,直接登出 localStorage.removeItem('authTokens') setAuthTokens(null) setUser(null) navigate('/login') } } }, [navigate])
4. 补全Django端JWT配置
你当前的SIMPLE_JWT配置缺少闭合括号,补全后确保后端返回正确的401状态码:
SIMPLE_JWT = { "ACCESS_TOKEN_LIFETIME": timedelta(seconds=4), "REFRESH_TOKEN_LIFETIME": timedelta(days=90), "ROTATE_REFRESH_TOKENS": True, "BLACKLIST_AFTER_ROTATION": True, "UPDATE_LAST_LOGIN": False, }
可选优化:自动刷新令牌
若需避免用户频繁登录,可在access token过期前调用/api/token/refresh/接口获取新令牌,更新本地存储并重置定时器,实现无感续期。
内容的提问来源于stack exchange,提问作者Tassaras Tassakos
相关产品推荐
相关产品推荐

