• 【RuoYi项目分析】网关的AuthFilter完成“认证”,注意是认证而不是权限



    过滤器的功能是检验经过网关的每一个请求,检查 token 中的信息是否有效。

    注意是“认证检查”,而不是“权限”,权限是在每个服务的Controller上贴权限注解

    1. 功能介绍

    1、在用户完成登录后,程序会把用户相关的用户、角色、权限等信息临时存储在 redis 中,并把token返回给终端用户。

    1、毕竟返回的token只存储了极其少量的用户信息,避免传输的数据量太大

    2、RuoYi 返回的 token 中存储的信息有:

    user_key:login_tokens:uuid(存入redis中用的)

    user_id:userId

    username:userName

    2、当用户携带token时,我们判断 token 是否有效,关联的用户是否登录。如果token有效就把user_key、user_id、username 设置到请求头中

    此处主要是检验 token 是否有效。

    设置到请求头,统一处理,也方便其他模块

    2. AuthFilter的配置

    @Component
    public class AuthFilter implements GlobalFilter, Ordered
    {
        private static final Logger log = LoggerFactory.getLogger(AuthFilter.class);
        
        @Autowired
        private RedisService redisService;
    
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
        {
            ...
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    AuthFilter 实现了GlobalFilter, Ordered,是一个全局过滤器,所有的模块都有。这也很好理解,所有的模块当然都需要检查 token 是否有效啊。

    3. AuthFilter实现分析

        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
        {
            ServerHttpRequest request = exchange.getRequest();
            ServerHttpRequest.Builder mutate = request.mutate();
    
            String url = request.getURI().getPath();
            // 1、检验路径
            if (StringUtils.matches(url, ignoreWhite.getWhites()))
            {
                return chain.filter(exchange);
            }
            String token = getToken(request);
            // 2、是否有token
            if (StringUtils.isEmpty(token))
            {
                return unauthorizedResponse(exchange, "令牌不能为空");
            }
            // 3、解析token,判断是否是有效的token
            Claims claims = JwtUtils.parseToken(token);
            if (claims == null)
            {
                return unauthorizedResponse(exchange, "令牌已过期或验证不正确!");
            }
            String userkey = JwtUtils.getUserKey(claims);
            // 4、判断用户是否登录
            boolean islogin = redisService.hasKey(getTokenKey(userkey));
            if (!islogin)
            {
                return unauthorizedResponse(exchange, "登录状态已过期");
            }
            String userid = JwtUtils.getUserId(claims);
            String username = JwtUtils.getUserName(claims);
            // 5、检查token是否有userId、userName
            if (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username))
            {
                return unauthorizedResponse(exchange, "令牌验证失败");
            }
    
            // 6、设置用户信息到请求
            addHeader(mutate, SecurityConstants.USER_KEY, userkey);
            addHeader(mutate, SecurityConstants.DETAILS_USER_ID, userid);
            addHeader(mutate, SecurityConstants.DETAILS_USERNAME, username);
            // 7、内部请求来源参数清除
            removeHeader(mutate, SecurityConstants.FROM_SOURCE);
            return chain.filter(exchange.mutate().request(mutate.build()).build());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    1、检验路径

    路径uri白名单检验,如果是白名单,直接通过。

    2、是否有token

    3、解析token,判断是否是有效的token

    只有有效的 token 才会解析出信息而不报错。

    4、判断用户是否登录

    auth 的权限校验有一个校验用户是否登录的注解。

    5、检查token是否有userId、userName

    6、设置用户信息到请求头

    7、内部请求来源参数清除

    8、继续下一个过滤器

    4. 资料参考

    语雀笔记地址:https://www.yuque.com/yuchangyuan/tkb5br

  • 相关阅读:
    【FPGA教程案例66】硬件开发板调试6——基于FPGA的UDP网口通信和数据传输
    牛客多校九 - Here is an Easy Problem of Zero-chan (树形DP,推公式,贡献)
    【花雕动手做】有趣好玩的音乐可视化系列小项目(18)--LED平面板灯
    k8s.gcr.io/kube-state-metrics/kube-state-metrics 拉取镜像失败问题解决
    金三银四怎么提高面试效率?不想去的公司要参加面试吗?
    任意文件下载(读取)
    智能化新十年,“全栈智能”定义行业“Copilot智能助手”
    网站文章被百度快速收录的工具
    雷军3小时演讲感受
    不堆概念、换个角度聊多线程并发编程
  • 原文地址:https://blog.csdn.net/yuchangyuan5237/article/details/133473706