使用aop去实现token校验

前言

昨天去面试,被问懵的一个面试题,面试官看了一下简历,轻笑了一声原来你是用拦截器做的token校验啊,那么改用aop你怎么去做校验。我当时脑袋一篇空白。下面就写个小demo

aop通知

先回顾一下aop的通知,aop通知有五中分别如下

  • 前置通知:方法执行前通知
  • 后置通知:方法执行后通知
  • 环绕通知:方法执行中通知
  • 异常抛出通知:方法抛出异常
  • 引介通知:类中增加新的方法属性

我们需要校验用户进行拦截oken,那么在执行到这个方法的时候拦截到,就需要用到环绕通知

导入Maven依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.21</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

实际代码

AOP拦截类

package com.yefeng.utils;

/**
 * @author 叶枫
 * @version 1.0.0
 * @create 2023/10/25 15:23
 */
import cn.hutool.jwt.JWTUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;

/**
 * 使用aop进行token校验
 * @author yefeng
 */
@Aspect
@Component
@Slf4j
public class TokenVerificationAop {
    /**
     * 登录路径 ->放行
     */
    private static final String LOGIN = "login";

    /**
     * @Pointcut 声明切入点表达式。
     * 注意此处扫描的是你的Controller层接口位置
     */
    @Pointcut("execution(public * com.yefeng.controller..*..*(..))")
    public void pointcut() {
    }

    /**
     * @Around 环绕通知
     * @Around("pointcut()") 可以理解为对这个方法进行环绕通知
     * ProceedingJoinPoint 参数 用于环绕通知,
     * 使用proceed()方法来执行目标方法,可以理解为 前置通知结束 开始执行使用该注解的方法。
     */
    @Around("pointcut()")
    public Object doBefore(ProceedingJoinPoint joinPoint) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert attributes != null;
        HttpServletRequest request = attributes.getRequest();
        String token = request.getHeader("Authorization");
        if (request.getRequestURI().contains(LOGIN)) {
            return joinPoint.proceed();
        }
        if (StringUtils.isNotBlank(token)) {
            try {
                JWTUtil.parseToken(token);
            } catch (Exception e) {
                // 解析jwt令牌出错, 说明令牌过期或者伪造等不合法情况出现 401
                log.info("AuthorizeFilter  解析jwt令牌出错", e);
                //此处可以返回自定义 Result结果对象 转成Json格式
                throw new Exception("解析jwt令牌出错");
            }
        } else {
            log.info("AuthorizeFilter  登录令牌不存在");
            throw new Exception("登录令牌不存在");
        }
        //执行业务逻辑,放行
        return joinPoint.proceed();
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值