如何在React Native中实现令牌过期时自动登出用户?
令牌过期自动登出实现方案
你的令牌管理器目前存在以下问题:登录状态下令牌过期后,若刷新令牌无效或请求失败,只会返回false但未触发登出逻辑,导致应用卡在加载界面,用户无法操作。下面是调整后的实现方案,添加自动登出功能:
核心修改点
- 新增专门的登出方法,负责清除所有存储的令牌和登录状态
- 在刷新令牌失败(包括refresh token无效、请求报错)时自动触发登出
- 修复原逻辑中无效的refresh token请求,避免无意义的错误请求
修改后的完整代码
const TokenManager = { // 新增登出方法:清除所有令牌并重置登录状态 logout: async () => { await DeviceStorage.clearToken(); await DeviceStorage.saveKey('isloggedIn', 'false'); // 这里可以添加跳转到登录页的逻辑,比如调用项目的导航函数 // 示例:navigation.navigate('Login'); }, restoreNewToken: async () => { const modelData = { client_id: TokenConfig.client_id, client_secret: TokenConfig.client_secret, grant_type: TokenConfig.grant_type, }; const token = await DeviceStorage.getKey('token'); const login_flag = await DeviceStorage.getKey('isloggedIn'); const current_time = new Date().getTime() / 1000; if (login_flag === 'true') { // 用户已登录 try { const jwt = jwt_decode(token); if (current_time > jwt.exp) { // 登录令牌已过期,尝试刷新 const refresh_token = await DeviceStorage.getKey('refresh_token'); const res = await axios.post( AppUrl.RefreshToken, qs.stringify({RefreshToken: refresh_token}), { headers: {'content-type': 'application/x-www-form-urlencoded'}, }, ); const data = res.data; if (data.error === 'invalid refresh token') { // 刷新令牌无效,自动登出 await TokenManager.logout(); return false; } else { // 刷新成功,保存新令牌 await DeviceStorage.saveKey('token', data.access_token); return true; } } else { // 令牌未过期,无需操作 return true; } } catch (error) { // 请求刷新令牌失败,自动登出 await TokenManager.logout(); console.log('令牌刷新失败:', error); return false; } } else { // 用户未登录,处理临时令牌 if (token === null) { try { const res = await axios.post( AppUrl.GetTemporaryToken, qs.stringify(modelData), { headers: {'content-type': 'application/x-www-form-urlencoded'}, }, ); const data = res.data; await DeviceStorage.saveKey('token', data.access_token); return true; } catch (error) { console.log('获取临时令牌失败:', error); return false; } } else { try { const jwt = jwt_decode(token); if (current_time > jwt.exp) { // 临时令牌过期,重新获取 const res = await axios.post( AppUrl.GetTemporaryToken, qs.stringify(modelData), ); const data = res.data; await DeviceStorage.saveKey('token', data.access_token); return true; } else { // 临时令牌未过期 return true; } } catch (error) { console.log('临时令牌校验失败:', error); return false; } } } }, clearAndRestoreNewToken: async () => { try { await DeviceStorage.clearToken(); await DeviceStorage.saveKey('isloggedIn', 'false'); const modelData = { client_id: TokenConfig.client_id, client_secret: TokenConfig.client_secret, grant_type: TokenConfig.grant_type, }; const res = await axios.post( AppUrl.GetTemporaryToken, qs.stringify(modelData), ); const data = res.data; await DeviceStorage.saveKey('token', data.access_token); return true; } catch (error) { console.log('清除令牌并重置失败:', error) return false; } }, }; export default TokenManager;
关键逻辑说明
- logout方法:统一处理登出流程,清除所有存储的令牌数据,并将
isloggedIn设为false,确保应用能识别用户已退出。你可以在这个方法里添加跳转到登录页面的导航逻辑。 - 刷新令牌失败处理:无论是refresh token无效还是请求报错,都会调用
logout方法,自动重置用户状态,避免应用卡在加载界面。 - 修复无效请求:原逻辑中清除令牌后还尝试获取refresh token并请求,这会导致无效请求,现在直接触发登出,避免无意义的错误。
内容的提问来源于stack exchange,提问作者Kritajna Shrestha
相关产品推荐
相关产品推荐

