需求分析
登录成功后,系统会返回一个token给客户端使用,token可以用来获取登录后的一些资源或者进行一些操作。当用户在系统中注销或者退出登录时,需要对token进行过期处理,以保证系统的安全性和数据的保护。以下是对登出成功后token过期需求分析的概述:
自动token过期: 当用户在系统中进行注销或者退出登录时,需要将该用户的token过期,禁止后续的使用。具体实现是,服务器应该在注销或退出登录时,将该用户token的状态设定为过期状态或者设置token的有效期为0,以保证token的及时失效。这种方式比手工管理token过期的方式高效、可靠并且节省时间和人力成本。 token黑名单机制: 当token失效后,服务器可以将这个token加入到一个黑名单中,以确保这个token失效不被误用。使用黑名单机制可以提升token失效之后的安全性,防止因失效而导致信息泄漏和数据损坏等问题。 多种方式保证token的有效性: 系统应该设定一个较短、可控制的token有效期限。在该有效期内,当客户端通过传递请求头信息携带token请求资源或服务时,服务器应该及时响应。如果在该有效期内由于某种原因导致服务器未能及时响应,则客户端应该自动或人工更新或请求获取新的token。 日志和监控: 需要对token过期和失效的记录进行审查和监测。通过监控系统,可以及时发现潜在的安全威胁,快速定位问题,并采取相应的措施,保障系统的安全性和稳定性。 以上是登出成功后token过期需求分析的一些基础内容,其他实际应用中还有更多的细节需要分析和处理。
解决方案
为了解决客户在
token
未过期期间退出登录,原颁发的token
还没有过期,我们采用redis
缓存未过期的token
(过期时间为该token
剩余过期时间),也可以把这种方式称为黑名单。
实现步骤
登出成功相关逻辑改造
由于我们集成了springsecurity,所以逻辑就写在了登出成功的拦截器中 具体实现步骤如下:
通过拦截器输入参数 HttpServletRequest
获取header
中的token
获取当前token的剩余过期时间 将该 token
添加到黑名单中,并设置过期时间为剩余过期时间
@Component
public class MyLogoutSuccessHandler implements LogoutSuccessHandler {
@Autowired
private RedisUtil redisUtil;
@Value("${jwt.authorization}")
private String authorization;
@Autowired
private JwtTokenUtils jwtTokenUtils;
@SneakyThrows
@Override
public void onLogoutSuccess(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
Authentication authentication) {
//获取token
String token = httpServletRequest.getHeader(authorization);
...
//获取当前token剩余毫秒数
long expiration = jwtTokenUtils.getExpirationTimeMillisFromToken(token);
//添加token黑名单
redisUtil.setEx(
RedisConstant.EXPIRATION_TOKEN
.concat(CommonConstant.COLON)
.concat(token),
JSON.toJSONString(allClaimsFromToken),
expiration,
TimeUnit.MILLISECONDS);
...
}
携带token请求相关逻辑
由于我们集成了springsecurity,所以逻辑就写在了自定义的拦截器中,接口携带token请求时会进入该拦截器 具体实现步骤如下:
通过拦截器输入参数 HttpServletRequest
获取header
中的token
校验token是否在黑名单中
@Component
public class JwtAuthorizationTokenFilter extends OncePerRequestFilter {
@Autowired
private JwtTokenUtils jwtTokenUtils;
@Value("${jwt.authorization}")
private String authorization;
@Autowired
private IUserService userService;
@Autowired
private RedisUtil redisUtil;
@SneakyThrows
@Override
protected void doFilterInternal(HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull FilterChain chain) {
//获取请求携带的token
final String token = request.getHeader(authorization);
//验证token是否为空
if (StringUtils.isNotBlank(token)) {
//验证token是否在黑名单中
if (!redisUtil.hasKey(RedisConstant.EXPIRATION_TOKEN.concat(CommonConstant.COLON).concat(token))) {
...
}
}
//继续执行
chain.doFilter(request, response);
}
}
原文始发于微信公众号(刘凌枫羽工作室):登出成功后token过期方案
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/251396.html