无感刷新Token? AT和RT是什么?

B站影视 2024-12-03 11:41 2

摘要:聊一个对于程序员来说非常常见的概念——Token过期,特别是JWT(JSON Web Token)如何通过“无感刷新”来解决这个问题。是不是感觉很复杂?别急,我会带你一步步解析清楚。我们从头开始,先看看常见的问题和解决办法。

聊一个对于程序员来说非常常见的概念——Token过期,特别是JWT(JSON Web Token)如何通过“无感刷新”来解决这个问题。是不是感觉很复杂?别急,我会带你一步步解析清楚。我们从头开始,先看看常见的问题和解决办法。

咱们有时候在使用某些系统,特别是像企业内部系统或者大型应用时,难免会碰到一个很让人恼火的问题:正在做事情,突然间系统就闪退了,跳转到登录页面。这时你可能想,“我明明还在做事,怎么就退出了?”其实,背后的原因很简单——Token过期了。

那么,什么是Token呢?简单来说,Token是一个认证凭证,就像我们用身份证、驾照来证明身份一样。在开发中,我们通常会使用JWT来生成这个Token,它是一种“轻量级”的凭证,可以用于传递用户信息。不过,Token也有个缺点——它有过期时间。一旦过期,用户的身份就不再有效,系统会强制用户重新登录。

Token过期问题的核心是JWT的生命周期。JWT通常由三部分组成:头部、载荷和签名。它的一个特点就是存储在客户端(比如浏览器的localStorage中),服务器在验证请求时根据Token来校验身份。而一旦Token过期,系统就认为用户身份失效,这时如果用户继续操作,就会被强制要求重新登录,造成闪退现象。

好在,解决这个问题的办法是有的,那就是自动刷新Token,也就是通过所谓的“无感刷新”来避免用户频繁登录。对于我们开发者来说,核心的思路就是,当Token快过期时,后端给客户端提供一个新的Token,而这一切过程,用户甚至是感受不到的。

那这个无感刷新是怎么实现的呢?实际上,它的核心原理并不复杂:

Token即将过期:后端会判断当前的Token是否快过期。刷新Token:如果Token快过期,后端会生成一个新的Token,返回给客户端。客户端更新Token:客户端接收到新的Token后,会自动更新本地存储的Token,避免用户再次登录。

这样一来,用户就能够在Token过期时,毫无感知地继续操作,不会被强制踢出系统。

实现Token无感刷新的关键,在于使用双Token机制。双Token机制通常包括两种Token:

Access Token(AT):这是用户每次请求时都会带上的Token,通常它的有效期较短,可能是几分钟、几小时。它的设计目的是减少泄漏后的风险,毕竟暴露在每次请求中的Token要比存储在服务器上的更容易被盗用。Refresh Token(RT):这是长期有效的Token,通常只有在认证时使用。Refresh Token的作用是,当Access Token过期时,客户端可以使用Refresh Token去请求后端生成新的Access Token。

简单来说,AT是用来访问资源的,RT则是用来更新AT的。它们是双保险,保证了用户即使频繁请求,也能保持良好的使用体验。

在后端,我们一般会通过判断AT的有效期,来决定是否需要刷新Token。下面我写个简单的示例,演示如何生成JWT Token,如何处理过期以及如何使用Refresh Token刷新Access Token。

public class JwtUtil { private static final String SECRET_KEY = "your_secret_key"; // 生成Access Token public static String generateAccessToken(String username) { return Jwts.builder .setSubject(username) .setExpiration(new Date(System.currentTimeMillis + 1000 * 60 * 15)) // 15分钟有效 .signWith(SignatureAlgorithm.HS512, SECRET_KEY) .compact; } // 生成Refresh Token public static String generateRefreshToken(String username) { return Jwts.builder .setSubject(username) .setExpiration(new Date(System.currentTimeMillis + 1000 * 60 * 60 * 24 * 7)) // 7天有效 .signWith(SignatureAlgorithm.HS512, SECRET_KEY) .compact; } // 解析Token public static Claims parseToken(String token) { return Jwts.parser .setSigningKey(SECRET_KEY) .parseClaimsJws(token) .getBody; } // 判断Token是否过期 public static boolean isTokenExpired(String token) { Date expiration = parseToken(token).getExpiration; return expiration.before(new Date); }}

当Access Token过期时,客户端会使用Refresh Token向后端请求刷新:

public String refreshaccessToken(String refreshToken) { // 验证Refresh Token是否有效 if (JwtUtil.isTokenExpired(refreshToken)) { throw new TokenExpiredException("Refresh Token is expired."); } // 获取用户信息 String username = JwtUtil.parseToken(refreshToken).getSubject; // 生成新的Access Token String newAccessToken = JwtUtil.generateAccessToken(username); return newAccessToken;}

在前端,处理Token续期也非常重要。一般来说,前端会在请求时检查Token是否过期,并在Token即将过期时自动刷新。最常见的做法是,在发送请求之前,先检查Access Token的有效性。如果过期,就通过Refresh Token向后端请求新的Token,并更新本地存储的Token。

// 获取Access Tokenfunction getAccessToken { return localStorage.getItem('access_token');}// 获取Refresh Tokenfunction getRefreshToken { return localStorage.getItem('refresh_token');}// 发送请求,自动刷新Tokenasync function sendRequest(url, data) { let accessToken = getAccessToken; if (!accessToken) { return redirectToLogin; } try { const response = await axios.post(url, data, { headers: { 'Authorization': `Bearer ${accessToken}` } }); return response.data; } catch (error) { if (error.response && error.response.status === 401) { // 如果Token过期,使用Refresh Token刷新 const refreshToken = getRefreshToken; const newAccessToken = await refreshAccessToken(refreshToken); // 更新本地存储的Token localStorage.setItem('access_token', newAccessToken); // 重新发送请求 return sendRequest(url, data); } else { throw error; } }}// 刷新Access Tokenasync function refreshAccessToken(refreshToken) { const response = await axios.post('/refresh-token', { refresh_token: refreshToken }); return response.data.access_token;}

通过使用双Token机制(Access Token + Refresh Token),结合后端的无感刷新机制,客户端可以在Token过期时自动更新Token,确保用户体验不受影响。对前端而言,可以通过检查Token有效性,自动进行刷新;而后端则通过生成新Token并返回来完成续期操作。最重要的是,这一切用户是感知不到的,免去了频繁登录和系统闪退的麻烦。

这就是今天的分享,希望你们在做系统认证时,能轻松应对Token过期的问题,不再让用户感受到断点登录的烦恼!

来源:麻辣小王子

相关推荐