SpringCloud(8)----zuul权限校验、接口限流

项目代码GitHub地址https://github.com/yudiandemingzi/spring-cloud-study

一、权限校验搭建

正常项目开发时,权限校验可以考虑JWT和springSecurity结合进行权限校验,这个后期会总结,这里做个基于ZuulFilter过滤器进行一个简单的权限校验过滤。

对于组件zuul中,其实带有权限认证的功能,那就是ZuulFilter过滤器。ZuulFilter是Zuul中核心组件,通过继承该抽象类,覆写几个关键方法达到自定义调度请求的作用

使用到的组件包括:Eureka、Feign、Zuul,包括以下四个项目:

(1)Eureka-server: 7001 注册中心

(2)product-server : 8001 商品微服务

(3)order-server : 9001 订单微服务

(4)zuul-gateway : 6001 Zuul网关

有关四个服务的基本配置我这里就不写了,具体可以看之前几篇博客,这里只写LoginFilter权限校验类

1、LoginFilter类

/**
 * 登录过滤器 *记得类上加Component注解
 */
@Component
public class LoginFilter extends ZuulFilter {

    /**
     * 过滤器类型,前置过滤器
     */
    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    /**
     * 过滤器顺序,越小越先执行
     */
    @Override
    public int filterOrder() {
        return 4;
    }

    /**
     * 过滤器是否生效
     * 返回true代表需要权限校验,false代表不需要用户校验即可访问
     */
    @Override
    public boolean shouldFilter() {

        //共享RequestContext,上下文对象
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();

        System.out.println(request.getRequestURI());
        //需要权限校验URL
        if ("/apigateway/order/api/v1/order/save".equalsIgnoreCase(request.getRequestURI())) {
            return true;
        } else if ("/apigateway/order/api/v1/order/list".equalsIgnoreCase(request.getRequestURI())) {
            return true;
        } else if ("/apigateway/order/api/v1/order/find".equalsIgnoreCase(request.getRequestURI())) {
            return true;
        }
        return false;
    }

    /**
     * 业务逻辑
     * 只有上面返回true的时候,才会进入到该方法
     */
    @Override
    public Object run() throws ZuulException {

        //JWT
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();

        //token对象,有可能在请求头传递过来,也有可能是通过参数传过来,实际开发一般都是请求头方式
        String token = request.getHeader("token");

        if (StringUtils.isBlank((token))) {
            token = request.getParameter("token");
        }
        System.out.println("页面传来的token值为:" + token);
        //登录校验逻辑  如果token为null,则直接返回客户端,而不进行下一步接口调用
        if (StringUtils.isBlank(token)) {
            // 过滤该请求,不对其进行路由
            requestContext.setSendZuulResponse(false);
            //返回错误代码
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }
        return null;
    }
}

2、关键说明

(1)方法说明

filterType : filter类型,分为pre、error、post、 route

filterOrder: filter执行顺序,通过数字指定,数字越小,执行顺序越先

shouldFilter: filter是否需要执行 true执行 false 不执行

run : filter具体逻辑(上面为true那么这里就是具体执行逻辑)

(2)filter类型说明

pre: 请求执行之前filter

route: 处理请求,进行路由

post: 请求处理完成后执行的filter

error: 出现错误时执行的filter

3、测试

先在请求头和传参都不传token,校验失败:返回401状态码

在参数的时候传入token值

看后台输出

说明模拟校验通过,返回用户信息。

二、接口限流搭建

接口限流可以在nginx层面做限流,也可以在网关层面做限流,这里在网关层面做限流,基于guava框架来做网关限流。

先对guava框架限流的概念进行讲解下:

它的大致意思就是每一个请求进来先到桶里去拿令牌,拿到令牌的请求放行,假设你设置了1000个令牌,如果拿完了,那么后面来调接口的请求就需要排队等有新的令牌才能调用该接口。

OrderRateLimiterFilter限流过滤类

/**
 * 订单限流
 *其它和上面都一样,只是run()中逻辑不一样
 */
@Component
public class OrderRateLimiterFilter extends ZuulFilter {

    //每秒产生1000个令牌
    private static final RateLimiter RATE_LIMITER = RateLimiter.create(1000);

    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return -4;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();

        //只对订单接口限流
        if ("/apigateway/order/api/v1/order/save".equalsIgnoreCase(request.getRequestURI())) {
            return true;
        }
        return false;
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();

        //就相当于每调用一次tryAcquire()方法,令牌数量减1,当1000个用完后,那么后面进来的用户无法访问上面接口
        //当然这里只写类上面一个接口,可以这么写,实际可以在这里要加一层接口判断。
        if (!RATE_LIMITER.tryAcquire()) {
            requestContext.setSendZuulResponse(false);
            //HttpStatus.TOO_MANY_REQUESTS.value()里面有静态代码常量
            requestContext.setResponseStatusCode(HttpStatus.TOO_MANY_REQUESTS.value());
        }
        return null;
    }
}

我只是偶尔安静下来,对过去的种种思忖一番。那些曾经的旧时光里即便有过天真愚钝,也不值得谴责。毕竟,往后的日子,还很长。不断鼓励自己,

天一亮,又是崭新的起点,又是未知的征程(上校10)

转载至:https://www.cnblogs.com/qdhxhz/p/9601170.html

原文地址:https://www.cnblogs.com/wllcs/p/12002850.html

时间: 2024-11-04 16:49:22

SpringCloud(8)----zuul权限校验、接口限流的相关文章

Guava的RateLimiter实现接口限流

最近开发需求中有需要对后台接口进行限流处理,整理了一下基本使用方法. 首先添加guava依赖: <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>23.0</version> </dependency> 然后封装RateLimiter适用对多接口的限制: import com.goog

java接口限流算法

0. 前言 常见的限流算法有:令牌桶.漏桶.计数器也可以进行粗暴限流实现. 1. 算法介绍 1.1 令牌桶算法 令牌桶算法是一个存放固定容量令牌的桶,按照固定速率往桶里添加令牌.令牌桶算法的描述如下: 假设限制2r/s,则按照500毫秒的固定速率往桶中添加令牌: 桶中最多存放b个令牌,当桶满时,新添加的令牌被丢弃或拒绝: 当一个n个字节大小的数据包到达,将从桶中删除n个令牌,接着数据包被发送到网络上: 如果桶中的令牌不足n个,则不会删除令牌,且该数据包将被限流(要么丢弃,要么缓冲区等待). 1.

【Dnc.Api.Throttle】适用于.Net Core WebApi接口限流框架

Dnc.Api.Throttle    适用于Dot Net Core的WebApi接口限流框架 使用Dnc.Api.Throttle可以使您轻松实现WebApi接口的限流管理.Dnc.Api.Throttle支持IP.用户身份.Request Header.Request QueryString等多种限流策略,支持黑名单和白名单功能,支持全局拦截和单独Api拦截. Dnc.Api.Throttle暂时只支持Redis作为缓存和存储库,后续会进行扩展. 开始使用 安装Dnc.Api.Thrott

使用google的guova开发高并发下的接口限流

使用google的guova进行限流 1.guova的限流方式,在定时产生定量的令牌,令牌的数量限制了流量 2.增加一个订单接口限流类OrderRateFilter,继承ZuulFilter,并重载方法:filterType.filterOrder.shouldFilter.run ????filterType中return PRE_TYPE; ????fileterOrder中应该优先级最高,设为-4 ????shouldFilter中设置限流的方法(类似于鉴权) ???? RequestCo

接口限流实践

一.问题描述 某天A君突然发现自己的接口请求量突然涨到之前的10倍,没多久该接口几乎不可使用,并引发连锁反应导致整个系统崩溃.如何应对这种情况呢?生活给了我们答案:比如老式电闸都安装了保险丝,一旦有人使用超大功率的设备,保险丝就会烧断以保护各个电器不被强电流给烧坏.同理我们的接口也需要安装上“保险丝”,以防止非预期的请求对系统压力过大而引起的系统瘫痪,当流量过大时,可以采取拒绝或者引流等机制. 二.常用的限流算法 常用的限流算法有两种:漏桶算法和令牌桶算法,这篇博文介绍得比较清晰(过载保护算法浅

接口限流算法总结

背景 曾经在一个大神的博客里看到这样一句话:在开发高并发系统时,有三把利器用来保护系统:缓存.降级和限流.那么何为限流呢?顾名思义,限流就是限制流量,就像你宽带包了1个G的流量,用完了就没了.通过限流,我们可以很好地控制系统的qps,从而达到保护系统的目的.本篇文章将会介绍一下常用的限流算法以及他们各自的特点. 算法介绍 计数器法 计 数器法是限流算法里最简单也是最容易实现的一种算法.比如我们规定,对于A接口来说,我们1分钟的访问次数不能超过100个.那么我们可以这么做:在一开 始的时候,我们可

限流(二)接口限流

如果某个接口可能出现突发情况,比如"秒杀"活动,那么很有可能因为突然爆发的访问量造成系统奔溃,我们需要最这样的接口进行限流. 在上一篇"限流算法"中,我们简单提到了两种限流方式: 1)(令牌桶.漏桶算法)限速率,例如:每 5r/1s = 1r/200ms 即一个请求以200毫秒的速率来执行: 2)(计数器方式)限制总数.或者单位时间内的总数,例如:设定总并发数的阀值,单位时间总并发数的阀值. 一.限制总并发数 我们可以采用java提供的atomicLong类来实现

常用的接口限流算法

在开发高并发系统时,有三把利器用来保护系统:缓存.降级和限流.那么何为限流呢?顾名思义,限流就是限制流量,就像你宽带包了1个G的流量,用完了就没了.通过限流,我们可以很好地控制系统的qps,从而达到保护系统的目的.本篇将会介绍一下常用的限流算法以及他们各自的特点. 算法介绍 计数器法 计数器法是限流算法里最简单也是最容易实现的一种算法.比如我们规定,对于A接口来说,我们1分钟的访问次数不能超过100个.那么我们可以这么做:在一开始的时候,我们可以设置一个计数器counter,每当一个请求过来的时

SpringCloud Alibaba Sentinel实现熔断与限流

 官网:https://github.com/alibaba/Sentinel 中文:https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D 下载:https://github.com/alibaba/Sentinel/releases                                  运行: 1  初始化演示工程 1.1 大纲: 1.2  创建cloudalibaba-sentinel-service8401 po