SpringCloud Zuul服务网关实操

鉴权

接上篇来,写一个简单的鉴权

请求必须携带token参数,若无token,则拒绝请求

其中

  • filterType--过滤器类型,这里使用PRE_TYPE前置
  • filterOrder--过滤器顺序,数值越小优先级越高,这里放在前置数值(PRE_DECORATION_FILTER_ORDER)的前边
  • shouldFilter--填true
  • run--过滤器的具体运行
package com.viki.apigateway.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

/**
 * 前置过滤器,有token才允许访问
 * @Author Sakura
 * @Date 13/11/2019
 **/
@Component
public class TokenFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        //过滤器顺序,放到pre过滤器之前(值越小优先级越高)
        return PRE_DECORATION_FILTER_ORDER - 1;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

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

        //从url参数获取,也可以从cookie和header获取
        String token = request.getParameter("token");
        if(StringUtils.isEmpty(token)){
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }

        return null;
    }
}

限流

对流量的限制,避免因请求过大而引起不必要的损失。

房子pre过滤器中,时机是请求被转发之前调用,如果pre有多个过滤器,应放在最前边

有许多限流策略,这里选择令牌桶(token bucket)

SpringCloud Zuul服务网关实操_第1张图片

发牌器按固定速率向令牌桶中添加令牌,若令牌桶满,则丢弃,不满则继续放。请求过来时就会从桶中拿令牌,如果拿到就放行,拿不到就拒绝请求。

新建 RateLimitFilter 文件,使用谷歌集成的令牌桶

package com.viki.apigateway.filter;

import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.exception.ZuulException;
import com.viki.apigateway.exception.RateLimitException;
import org.springframework.stereotype.Component;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVLET_DETECTION_FILTER_ORDER;

/**
 * 限流
 * @Author Sakura
 * @Date 13/11/2019
 **/
@Component
public class RateLimitFilter extends ZuulFilter {

    //google令牌桶,每秒放100个
    private static RateLimiter RATE_LIMITERR = RateLimiter.create(100);

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

    @Override
    public int filterOrder() {
        //最高优先级(比最小的数小)
        return SERVLET_DETECTION_FILTER_ORDER - 1;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {

        if(!RATE_LIMITERR.tryAcquire()){
            throw new RateLimitException();
        }
        return null;
    }
}

跨域

ajax存在同源策略,违反同源策略就会产生同源问题。解决同源问题有两种思路

  • 使用@CrossOrigin注解,不过这是针对方法而言
  •   在zuul中统一配置,针对对所有项目

zuul统一配置方法

package com.viki.apigateway.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import java.util.Arrays;

/**
 * 跨域配置
 * @Author Sakura
 * @Date 13/11/2019
 * C - Cross   O - Origin  R - Resource  S - Sharing
 **/
@Configuration
public class CorsConfig {

    @Bean
    public CorsFilter corsFilter(){
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();

        config.setAllowCredentials(true);  //允许cookie跨域
        config.setAllowedHeaders(Arrays.asList("*")); //允许所有头
        config.setAllowedMethods(Arrays.asList("*")); //允许所有方法,GET,POST等
        config.setAllowedOrigins(Arrays.asList("*"));  //原始域,比如自己的www.viki.com
        config.setMaxAge((long) 3001); //缓存时间,指定时间段内不再检查

        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

 

你可能感兴趣的:(SpringCloud)