登出成功后token过期方案

需求分析

登录成功后,系统会返回一个token给客户端使用,token可以用来获取登录后的一些资源或者进行一些操作。当用户在系统中注销或者退出登录时,需要对token进行过期处理,以保证系统的安全性和数据的保护。以下是对登出成功后token过期需求分析的概述:

  1. 自动token过期: 当用户在系统中进行注销或者退出登录时,需要将该用户的token过期,禁止后续的使用。具体实现是,服务器应该在注销或退出登录时,将该用户token的状态设定为过期状态或者设置token的有效期为0,以保证token的及时失效。这种方式比手工管理token过期的方式高效、可靠并且节省时间和人力成本。
  2. token黑名单机制: 当token失效后,服务器可以将这个token加入到一个黑名单中,以确保这个token失效不被误用。使用黑名单机制可以提升token失效之后的安全性,防止因失效而导致信息泄漏和数据损坏等问题。
  3. 多种方式保证token的有效性: 系统应该设定一个较短、可控制的token有效期限。在该有效期内,当客户端通过传递请求头信息携带token请求资源或服务时,服务器应该及时响应。如果在该有效期内由于某种原因导致服务器未能及时响应,则客户端应该自动或人工更新或请求获取新的token。
  4. 日志和监控: 需要对token过期和失效的记录进行审查和监测。通过监控系统,可以及时发现潜在的安全威胁,快速定位问题,并采取相应的措施,保障系统的安全性和稳定性。 以上是登出成功后token过期需求分析的一些基础内容,其他实际应用中还有更多的细节需要分析和处理。

解决方案

为了解决客户在token未过期期间退出登录,原颁发的token还没有过期,我们采用redis缓存未过期的token(过期时间为该token剩余过期时间),也可以把这种方式称为黑名单。

实现步骤

登出成功相关逻辑改造

由于我们集成了springsecurity,所以逻辑就写在了登出成功的拦截器中 具体实现步骤如下:

  1. 通过拦截器输入参数HttpServletRequest获取header中的token
  2. 获取当前token的剩余过期时间
  3. 将该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请求时会进入该拦截器 具体实现步骤如下:

  1. 通过拦截器输入参数HttpServletRequest获取header中的token
  2. 校验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

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!