1,权限校验:
package com.taotao.steam.gateway.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
* @author aping
* @time 2020/5/3 11:28
*/
@Component
@Slf4j
public class TokenFilter extends ZuulFilter {
/**
* 过滤类型 pre 表示在请求之前进行执行
* @return
*/
@Override
public String filterType() {
return "pre";
}
/**
* 过滤器执行顺序 ,当一个请求在同一阶段的时候存在多个过滤器的时候,多个过滤器执行顺序
* @return
*/
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
//共享RequestContext,上下文对象
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
System.out.println(request.getRequestURI());
//需要权限校验URL
if ("/swagger-ui.html/**".equalsIgnoreCase(request.getRequestURI())) {
return true;
} else if ("/api-aop/**".equalsIgnoreCase(request.getRequestURI())) {
return true;
}else if ("/api-backstage/**".equalsIgnoreCase(request.getRequestURI())) {
return true;
}else if ("/api-community/**".equalsIgnoreCase(request.getRequestURI())) {
return true;
}
return false;
}
/**
* 编写业务逻辑代码
* @return
* @throws ZuulException
*/
@Override
public Object run() throws ZuulException {
//获取所有的服务接口,判断服务是否有传递token
//1获取上下文
RequestContext currentcontext= RequestContext.getCurrentContext();
//获取request
HttpServletRequest request=currentcontext.getRequest();
String token=request.getParameter("userToken");
if(Strings.isBlank(token)){
currentcontext.setSendZuulResponse(false);
currentcontext.setResponseBody("token is null");
currentcontext.setResponseStatusCode(401);
}
log.info("通过过滤");
return null;
}
}
2,接口限流:
集成guava
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>29.0-jre</version>
</dependency>
接口限流可以在nginx层面做限流,也可以在网关层面做限流,这里在网关层面做限流,基于guava框架来做网关限流。
先对guava框架限流的概念进行讲解下:
的大致意思就是每一个请求进来先到桶里去拿令牌,拿到令牌的请求放行,假设你设置了1000个令牌,如果拿完了,那么后面来调接口的请求就需要排队等有新的令牌才能调用该接口。
package com.taotao.steam.gateway.filter;
import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
* 接口限流
* @author aping
* @time 2020/5/3 16:02
*/
@Component
public class OrderRateLimiterFilter extends ZuulFilter {
//每秒差生1000个令牌
private static final RateLimiter RATE_LIMITER=RateLimiter.create(1);
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
RequestContext requestContext=RequestContext.getCurrentContext();
HttpServletRequest request =requestContext.getRequest();
//只对特定接口限流
if("/api-aop/**".equals(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;
}
}