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)")
  
  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值