IT技术

spring-cloud-zuul API网关

2018-03-02  本文已影响220人  even_366
1.业务流程图
API服务接口调用认证流程图_new.jpg
2. 需要依赖包pom.xml
<dependency>
    ##自定义异常封装
    <groupId>com.exception</groupId>
    <artifactId>exctption</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.41</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
3.application.yml文件,zull 路由配置采用path和URL方式
zuul:
  routes:
    user-center:
     path: /api/user/**
     url: http://127.0.0.1:9001/user #用户中心服务
    log-service:
     path: /api/logs/**
     url: http://127.0.0.1:9092/log  #日志服务
    test-service:
     path: /api/test/**
     url: http://127.0.0.1:9003/test #测试服务

这样可以将/api/user/**映射到http://127.0.0.1:9001/user
需要注意这种方式路由不会被HystrixCommand执行,同时不能使用Ribbon来负载多个url。

3.编写自定义Access过滤器
public class AccessFilter extends ZuulFilter {

    @Autowired
    private TokenService tokenService;
    private Logger logger = LoggerFactory.getLogger(getClass());
    private final static String token="token";
    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 0;
    }

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

    @Override
    public Object run() {
        RequestContext ctx=RequestContext.getCurrentContext();
        HttpServletRequest request=ctx.getRequest();
        String url=request.getRequestURI().toString();
        List l=new ArrayList();
        l.add("logs");
        logger.info("send {} request to {}",request.getMethod(),url);
        Object token=request.getHeader(AccessFilter.token);
        //判断token不能为空
        if(StringUtils.isEmpty(token)){
            this.returnMsg(ctx,"token is empyt");
        }
        try {
            //String v=tokenService.checkToken(token.toString());
           // if(StringUtils.isEmpty(v)){
           //     this.returnMsg(ctx,"token is inexistence");
          //  }
            String service=ConvertCollect.stringToStringArr(url,"/")[3];
            if(!this.chooseRout(l,service)){
                this.returnMsg(ctx,"no authorization "+service);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }



    //返回没权限消息
    private void returnMsg(RequestContext ctx,String msg){
        ctx.getResponse().setContentType("application/json; charset=utf-8");
        ctx.setSendZuulResponse(false); //令zuul过滤该请求,不对其进行路由
        Result result= ResultUtil.error(401,msg);
        ctx.setResponseBody(JSON.toJSONString(result));
    }



    /**
     * 根据url验证是否有权限
     * @param list
     * @param service
     * @return
     */
    private boolean chooseRout(List<String> list, String service){
        switch (service){
            case ServiceName.user:
                return isAuth(list,service);
            case ServiceName.test:
                return isAuth(list,service);
            case ServiceName.logs:
                return isAuth(list,service);
        }
        return false;
    }
    /**
     * 判断token是否有service权限
     * @param list
     * @param userAuthService 用户拥有服务权限
     * @return
     */
    private boolean isAuth(List<String> list, String userAuthService){
        return list.contains(userAuthService);
    }
上一篇下一篇

猜你喜欢

热点阅读