springcloud zull网关搭建 及请求参数传递问题

zull网关搭建

zull: 统一请求路径,将请求分发给相应的微服务中 。请求直接发送到zull就行,不用关注每个微服务的端口号
zull搭建(开发工具使用的是idea)

  1. 新建module添加依赖(这里的父工程仅是一个springboot工程)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>tensquare_parent</artifactId>
        <groupId>com.tensquare</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>tensquare_manager</artifactId>
    <dependencies>
    //eureka客户端依赖
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        //zull网关依赖
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
        <dependency>
            <groupId>com.tensquare</groupId>
            <artifactId>tensquare_commen</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>
  1. 添加配置application.yml(此步骤注意缩进)
server:
  port: 9011
spring:
  application:
    name: tensquare-manager #指定服务名
eureka:
  client:
    serviceUrl: #Eureka客户端与Eureka服务端进行交互的地址
      defaultZone: http://127.0.0.1:6868/eureka/
  instance:
    prefer-ip-address: true
zuul:
  routes:
    tensquare-base: # 项目名称,自由填写
      path: /base/** #配置请求URL的请求规则
      serviceId: tensquare-base #指定Eureka注册中心中的服务id
    tensquare-qa: # 项目名称,自由填写
      path: /qa/** #配置请求URL的请求规则
      serviceId: tensquare-qa #指定Eureka注册中心中的服务id
    tensquare-friend: # 项目名称,自由填写
      path: /friend/** #配置请求URL的请求规则
      serviceId: tensquare-friend #指定Eureka注册中心中的服务id
    tensquare-user: # 项目名称,自由填写
      path: /user/** #配置请求URL的请求规则
      serviceId: tensquare-user #指定Eureka注册中心中的服务id
      //将zull敏感请求头设置为空,否则可能出现请求参数不能传递给微服务
  sensitiveHeaders=
jwt:
  config:
    key: itcast # 密钥(加盐)
  1. 添加启动类
@SpringBootApplication
@EnableZuulProxy
//注意不要写成@EnableZuulServer
public class ZuulApplication {
    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication.class);
    }
}

  1. 启动 eureka服务注册微服务,再启动zull网关
  2. 报错解决:
    连接server失败或找不到server
    首先确认eureka启动是否成功,不成功排查rureka的配置文件一定要配置registerWithEureka、 fetchRegistry为false正确配置如下
server:
  port: 6868 #服务端口
eureka:
  client:
    registerWithEureka: false #是否将自己注册到Eureka服务中,本身就是所有无需注册
    fetchRegistry: false #是否从Eureka中获取注册信息
    serviceUrl: #Eureka客户端与Eureka服务端进行交互的地址
      defaultZone: http://127.0.0.1:${server.port}/eureka/

其次确认网关的配置文件缩进是否正确,缩进不正确导致层级关系错误,也会导致不能连接server

zull请求头转发不能获取问题

为什么存在zull转发请求头问题?
因为zull复制请求,发送给微服务。但是zull只复制标准请求头,不复制自定义的请求头传递token用的自定义"Authorization"头,因此要手动将非标准头转发给后端微服务。
例子
zull拦截请求并验证token

//获取原生request
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        if(request.getMethod().equals("OPTIONS")){
            //直接放行OPTIONS方式的请求,供网关使用
            return null;
        }
        //提取请求地址
        String url=request.getRequestURL().toString();
        if(url.indexOf("/admin/login")>0||url.indexOf("/admin/register")>0){ //判断如果是登录页面=>直接放行,不需要校验管理员权限
            System.out.println("登陆页面"+url);
            return null;
        }
        String authHeader =(String)request.getHeader("Authorization");//获取头信息
        //判断是否存在
        if (authHeader!=null&&authHeader.startsWith("Bearer ")){
            String token = authHeader.substring(7);
            Claims claims = jwtUtil.parse(token); //解析token
            if (claims!=null){
                if ("admin".equals(claims.get("role"))){//=>是管理员,转发到微服务中,并携带Authorization头
                    currentContext.addZuulRequestHeader("Authorization",authHeader);
                    return null;
                }
            }

        }
        //当前用户未登录,或角色不是管理员 => 阻止网关转发
        currentContext.setSendZuulResponse(false);//终止运行
        currentContext.setResponseStatusCode(401);//指定返回响应的状态码
        //为响应添加ContentType头
        currentContext.getResponse().setContentType("text/html;charset=UTF‐8");
        currentContext.setResponseBody("no privilege!"); //指定响应内容
        return null;

微服务获取请求头

String authorization = request.getHeader("Authorization");

        if (authorization!=null&&!"".equals(authorization)&&authorization.startsWith("Bearer ")){
            //解析token
            String token = authorization.substring(7);
            Claims claims = jwtUtil.parse(token);
            if (claims==null){
                return  false;
            }
            String role = (String)claims.get("role");
            if ("admin".equals(role)){
                request.setAttribute("admin_role",role);
                System.out.println("jwt载荷放入admin_role");
            }
            if ("user".equals(role)){
                request.setAttribute("user_role",role);
                System.out.println("jwt载荷放入user_role");
            }
            return true;
        }

        System.out.println("拦截器拦截"+request.getAttribute("admin_role"));
        //执行操作
        return false;

错误解决:
后端微服务接收到的"Authorization"请求头为null

      if ("admin".equals(claims.get("role"))){//=>是管理员,转发到微服务中,并携带Authorization头
                    currentContext.addZuulRequestHeader("Authorization",authHeader);
                    return null;
                }

确认zull已经将token放入到"Authorization"。
原因: Authorization是敏感头,zull并不会转发这个请求头
解决:

  1. 不要使用敏感字段,改成"Authorization1"就可以
  2. 在配置文件中配置zull的敏感字段为空
sensitiveHeaders=
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值