1.什么是spring 的Aop(面向切面编程)的组成
我们都知道AOP 有切入点,连接点,切面等,我们就用这个方法进行对token的验证
2.首先先引入aop依赖jar包
< <!--aop-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.7.10</version>
3.创建一个AuthAspect类
4.完整的token验证(如果有什么不清楚的,可以去百度看注解的意思)
@Aspect //就是把一个类定义为切面供容器读取。每次执行方法之前,先执行这里面的代码
public class AuthAspect {
//匹配controller.auth类下面的所有共有方法。
//访问controller.auth里面的类的方式的时候 需要进行token验证,访问controller外层的接口的时候不需要验证token
@Pointcut("execution(public * com.example.jwtdemo.*.controller.auth.*.*(..))")
public void loc() throws Exception {
}
@Before("loc()")
//@Before:在方法执行前执行该方法(在请求controller方法前先验证token是否合法),并且可以通过(JoinPoint类)获取请求参数和方法
public void doBefore(JoinPoint joinPoint) {
//通过joinPoint里面的信息,获取出来对token的验证
//1.首先用户登录的时候,先把用户信息加密,变成token,缓存在redis中也可以
//2.当前端传token进行调用接口的时候,先通过这个验证token是否合法以及没有过期
/**
RequestDto requestDto = (RequestDto) joinPoint.getArgs()[0];//RequestDto 这个是我封装的类
String token = requestDto.getToken();
if (!tomany) log.info("token={}", token);
if (StringUtils.isBlank(token)) throw new ApiException(ApiEnum.login_no);token为空返回错误信息
boolean check = !httpServletRequest.getRequestURI().contains("/user/approve");
Long userId = tokenService.tokenCheck(token, check); //用redis通过token获取到userId在于解密后的userId进行验证
String s = redisService.getToken(userId + "");
if (!token.equals(s))throw new ApiException(ApiEnum.log_error);
if (userId == null) throw new ApiException(ApiEnum.login_no);
requestDto.setTokenUser(userId); //验证成功之后,TokenUser就等于用户的id
*/
}
//@AfterReturning: 返回通知,在方法返回结果之后执行。可以打印出来你获取到数据
@AfterReturning(returning = "object", pointcut = "loc()")
public void doAfterReturning(Object object) {
// log.info("responce={}", object);
}
//@AfterThrowing:异常通知,在方法抛出异常之后执行。通过日志打印错误信息
@AfterThrowing(pointcut = "loc()", throwing = "e")
public void afterThrowable(JoinPoint joinPoint, Throwable e) {
//方法名获取
String methodName = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
// log.error("请求异常:请求方法:{}, 异常信息:{}", methodName, Throwables.getStackTraceAsString(e));
}
}
5.封装的RequestDto
6.controller类的传参
前端通过这个类传token,就可以直接获取到userId进行调用