当前位置: 首页 > news >正文

AOP 切面判断 token 是否有效

需求:

  1. 接口必须传入 token
  2. token 必须有效
  3. token 未过期

maven 依赖

  • 引入 aop 做切面
  • 引入 hutool 做 JWT 解析
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>${springframework.version}</version>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-core</artifactId>
    <version>${hutool-core.version}</version>
</dependency>

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>${hutool-all.version}</version>
</dependency>

 
关键代码

  • 使用 @Before 在流量进入接口前先检验
  • 获取过期时间戳
  • 过期需要抛出异常
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil; 
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.time.Instant;
import java.util.Objects;

@Aspect
@Component
@Slf4j
public class AuthorizationAspect {

    @Before("execution(* com.xxx.controller.*.*(..))")
    public void checkAuthorization(JoinPoint joinPoint) {
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(Objects.requireNonNull(RequestContextHolder.getRequestAttributes()))).getRequest();
        String authorizationHeader = request.getHeader("Authorization");
        Assert.isTrue(StringUtils.isBlank(authorizationHeader), TokenExpireEnum.NULL);
        Assert.isTrue(isExpireAuthorization(authorizationHeader), TokenExpireEnum.EXPIRE);
    }

    /**
     * 判断token是否过期
     *
     * @param jwtToken 令牌
     * @return 是否过期
     */

    private boolean isExpireAuthorization(String jwtToken) {
        JWT jwt = null;
        try {
            jwt = JWTUtil.parseToken(jwtToken);
        } catch (Exception e) {
            Assert.throwException(TokenExpireEnum.PARSE);
        }

        Object expObj = jwt.getPayload("exp");
        Long exp = Convert.convert(new TypeReference<Long>() {
        }, expObj);
        Instant now = Instant.now();
        Instant timeStampInstant = Instant.ofEpochSecond(exp);
        if (now.isAfter(timeStampInstant)) {
            log.error("token expired, time: {}", timeStampInstant);
            return true;
        }
        return false;
    }
}

 
这样问题来了,登录获取 token 的接口也被拦截调了,两个办法

  1. @Before 可以排除不需要拦截类
  2. 新增注解,在不需要 token 校验的方法加上

这里举例方法二

新建注解 ExcludeAuthorizationCheck

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcludeAuthorizationCheck {
}

@Before 排除注解 ExcludeAuthorizationCheck

  @Before("execution(* com.xxx.controller.*.*(..)) && !@annotation(com.xxx.ExcludeAuthorizationCheck)")
  

相关文章:

  • OpenAI的Whisper
  • Vue3学习01 Vue3核心语法
  • 大语言模型的指令调优:综述
  • 基于STM32的智能交通系统设计与实现
  • 液冷方式介绍
  • 在Debian 12系统上安装Docker
  • 专业级股票交易系统 股票金融平台 带新股申购 通信达源码
  • three.js尝试渲染gbl模型成功!(三)
  • unable to find a medium containing a live file system解决办法!
  • 深入浅出 -- 系统架构之负载均衡Nginx的性能优化
  • 深入浅出 -- 系统架构之负载均衡Nginx反向代理
  • Go语言map、slice、channel底层实现(go面试)
  • Harmony鸿蒙南向驱动开发-DAC
  • 损失函数:BCE Loss(二元交叉熵损失函数)、Dice Loss(Dice相似系数损失函数)
  • SSM实战项目——哈哈音乐(二)后台模块开发
  • Node.js环境调用百度智能云(百度云)api鉴权认证三步走
  • 北航计算机软件技术基础课程作业笔记【3】
  • Java项目:基于Springboot+vue实现的中国陕西民俗前后台管理系统设计与实现(源码+数据库+毕业论文)
  • ICP配准算法
  • 计算机专业,不擅长打代码,考研该怎么选择?
  • https://app.hackthebox.com/machines/Inject
  • Spring —— Spring简单的读取和存储对象 Ⅱ
  • 渗透测试之冰蝎实战
  • Mybatis、TKMybatis对比
  • Microsoft Office 2019(2022年10月批量许可版)图文教程
  • 《谷粒商城基础篇》分布式基础环境搭建
  • 哈希表题目:砖墙
  • Vue 3.0 选项 生命周期钩子
  • 【车载嵌入式开发】AutoSar架构入门介绍篇
  • 【计算机视觉 | 目标检测】DETR风格的目标检测框架解读