• SpringBoot


    前言

    记录下AOP实现登录状态的检查,文章使用的JWT校验参考:SpringBoot - 集成Auth0 JWT


    实现登录状态检查的方式

    • Servlet过滤器
    • 拦截器
    • Spring AOP

    AOP 定义

    AOP(Aspect Oriented Programming),面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术,在程序开发中主要用来解决一些系统层面上的问题,在不改变原有的逻辑的基础上,增加一些额外的功能,如日志,事务,权限等


    AOP 相关概念

    术语 概念 描述
    Aspect 切面 通知和切点的集合
    Joint point 连接点 应用执行过程中能够插入切面的一个点
    Advice 通知 定义切面是什么以及何时使用
    Pointcut 切点 定义切面在何处执行,切点的定义会匹配通知所有要织入的连接点
    Weaving 织入 把切面应用到目标对象并创建新的代理代理对象的过程

    Advice 通知类型

    术语 概念 描述
    Before 前置通知 在目标方法被调用之前调用通知功能
    After 后置通知 在目标方法完成之后调用,此时不关心方法的输出是什么
    AfterReturning 返回通知 在目标方法成功执行之后调用通知
    AfterThrowing 异常通知 在目标方法抛出异常后调用通知
    Around 环绕通知 通知包裹了通知的方法,在被通知的方法调用之前和调用之后执行自定义行为

    具体实现

    实现代码

    • 自定义注解CheckLogin
    /**
     * @Description 登录校验注解
     * @author coisini
     * @date Oct 14, 2021
     * @Version 1.0
     */
    public @interface CheckLogin {
    }
    
    • 切面CheckLoginAspect
    import com.coisini.aop.util.JwtUtil;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.http.HttpStatus;
    import org.springframework.stereotype.Component;
    import org.springframework.web.context.request.RequestAttributes;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    import javax.servlet.http.HttpServletRequest;
    
    /**
     * @Description 登录校验切面
     * @author coisini
     * @date Oct 14, 2021
     * @Version 1.0
     */
    @Aspect
    @Component
    public class CheckLoginAspect {
    
        /**
         * 只要加了@CheckLogin的方法都会走到这里
         * @param point
         * @return
         */
        @Around("@annotation(com.coisini.aop.auth.annotation.CheckLogin)")
        public Object checkLogin(ProceedingJoinPoint point) {
            try {
                // 从header中获取token
                RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
                ServletRequestAttributes attributes = (ServletRequestAttributes) requestAttributes;
                HttpServletRequest request = attributes.getRequest();
    
                String token = request.getHeader("token");
    
                // 校验token是否合法
                Boolean valid = JwtUtil.verifyToken(token);
                if (!valid) {
                    throw new ServerErrorException(HttpStatus.UNAUTHORIZED.value(), "Token 不合法");
                }
    
                // 执行后续的方法
                return point.proceed();
            } catch (Throwable throwable) {
                throw new ServerErrorException(HttpStatus.UNAUTHORIZED.value(), "Token 不合法");
            }
        }
    }
    
    • 自定义异常ServerErrorException
    import lombok.AllArgsConstructor;
    import lombok.Data;
    
    /**
     * @Description 自定义异常
     * @author coisini
     * @date Oct 14, 2021
     * @Version 1.0
     */
    @Data
    @AllArgsConstructor
    public class ServerErrorException extends RuntimeException{
    
        public Integer code;
        public String message;
    
    }
    
    • 统一异常处理GlobalExceptionAdvice
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RestControllerAdvice;
    
    /**
     * @Description 统一异常处理
     * @author coisini
     * @date Oct 14, 2021
     * @Version 1.0
     */
    @RestControllerAdvice
    @Slf4j
    public class GlobalExceptionAdvice {
    
        @ExceptionHandler(ServerErrorException.class)
        public ResponseEntity<UnifyMessage> handleServerErrorException(ServerErrorException e) {
    
            log.warn("ServerErrorException 异常", e);
    
            return new ResponseEntity<>(
                    UnifyMessage.builder()
                            .code(e.getCode())
                            .message(e.getMessage())
                            .build(),
                    HttpStatus.UNAUTHORIZED
            );
        }
    
    }
    
    • 统一消息返回UnifyMessage
    import lombok.AllArgsConstructor;
    import lombok.Builder;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    /**
     * @Description 统一消息返回
     * @author coisini
     * @date Oct 14, 2021
     * @Version 1.0
     */
    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    public class UnifyMessage {
    
        private int code;
        private String message;
    
    }
    

    测试

    • 测试方法TestController
    /**
     * AOP校验请求头中的Token
     * @return
     */
    @CheckLogin
    @GetMapping(value = "/test")
    public String testCheckLogin() {
        // TODO 业务
        return "Token验证通过";
    }
    
    • 获取Token

    在这里插入图片描述


    • Token测试

    在这里插入图片描述


    • 传递Token

    在这里插入图片描述



    源码

    GitHubhttps://github.com/maggieq8324/java-learn-demo/tree/master/springboot-aop


    - End -
    白嫖有风险
    点赞加收藏
    以上为本篇文章的主要内容,希望大家多提意见,如果喜欢记得点个推荐哦
    作者:Maggieq8324
    本文版权归作者和博客园共有,欢迎转载,转载时保留原作者和文章地址即可。
  • 相关阅读:
    Linux命令集
    Java实现 LeetCode 648 单词替换(字典树)
    pci常用命令
    pci 设备 vendor device subsystem 驱动
    手动绑定驱动 + drivers_probe + rescan
    找不到网卡 pci probe function not called
    primary + secondary + malloc + rte_memzone_reserve
    gdb 打印结构体
    rte_fbarray_init
    DPDK 内存管理---malloc_heap和malloc_elem
  • 原文地址:https://www.cnblogs.com/maggieq8324/p/15406015.html
Copyright © 2020-2023  润新知