在微服务架构中,Netflix Zuul 是一个常用的 API 网关。它可以对请求进行路由、过滤等操作。当请求在不同服务之间传递时,会涉及到请求头(Headers)的处理。
有些请求头可能包含敏感信息,如用户的认证令牌、用户的隐私数据等。sensitive-headers 配置就是用于控制 Zuul 在路由请求时如何处理这些敏感的请求头。
Zuul 默认会过滤掉一些敏感的请求头,例如 Cookie、Set-Cookie 和 Authorization。这是为了防止这些敏感信息被不小心泄露到下游服务。如下图:
这种默认行为是基于安全考虑,因为下游服务可能并不需要这些敏感信息,并且如果这些信息被错误地处理或记录,可能会导致安全漏洞。
假如我们在 service-product 服务中创建一个 SimpleController 控制器,定义一个 headers 方法,代码如下:
package com.hxstrive.service_demo.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; /** * 简单控制器 * @author hxstrive.com */ @RestController @RequestMapping("/simple") public class SimpleController { @GetMapping("/headers") public String headers(@RequestHeader(value = "Cookie", required = false) String cookie, @RequestHeader(value = "Authorization", required = false) String auth, HttpServletResponse response) { // 创建一个Cookie对象 Cookie cookieObj = new Cookie("user_id", "12345"); // 设置Cookie的路径,这里设置为整个应用('/') cookieObj.setPath("/"); // 设置Cookie的最大存活时间,单位是秒。这里设置为1小时(3600秒) cookieObj.setMaxAge(3600); // 将Cookie添加到响应中 response.addCookie(cookieObj); return "Cookie:" + cookie + "<br/> Authorization: " + auth; } }
上述代码中,headers 方法接收 Cookie 和 Authorization 请求头,并且通过 HttpServletResponse 的 addCookie() 方法设置一个名为 user_id 的 cookie 到前端。使用 ApiFox 调用接口如下图:
请求的 curl 如下:
curl --location --request GET 'http://localhost:8091/simple/headers' \ --header 'Cookie: token=myToken; user_id=12345' \ --header 'User-Agent: Apifox/1.0.0 (https://apifox.com)' \ --header 'Authorization: Bearer auth-value' \ --header 'Accept: */*' \ --header 'Host: localhost:8091' \ --header 'Connection: keep-alive'
响应内容如下:
从上可知,接口返回了 Set-Cookie 响应通,并且请求头 Cookie 和 Authorization 成功传递到了后端。
假如我们通过 Zuul 网关代理该接口,效果会是什么样子呢?curl 请求如下:
curl --location --request GET 'http://localhost:9000/api/product/simple/headers?token=myToken' \ --header 'User-Agent: Apifox/1.0.0 (https://apifox.com)' \ --header 'Authorization: Bearer auto value' \ --header 'Accept: */*' \ --header 'Host: localhost:9000' \ --header 'Connection: keep-alive' \ --header 'Cookie: user_id=12345'
响应结果:
从上图可知,客户端请求的 Cookie 和 Authorization 头并没有传递到后端,而且后端响应的 set-cookie 头也没有传递到前端。
下面介绍如何通过 zuul 敏感头配置来控制 Cookie、Authorization 和 Set-Cookie 不是敏感头,可正常传播。
在 application.yml 中配置:
zuul: # 指定 Cookie,Set-Cookie,Authorization 为敏感头,默认行为 sensitive-headers: Cookie,Set-Cookie,Authorization
如果我们将 sensitive-headers 设置为空,则表示没有敏感头字段,配置如下:
zuul: # 没有敏感头字段 sensitive-headers:
重启 Zuul 应用,重新访问 http://localhost:9000/api/product/simple/headers 地址,对应的 curl 为:
curl --location --request GET 'http://localhost:9000/api/product/simple/headers?token=myToken' \ --header 'User-Agent: Apifox/1.0.0 (https://apifox.com)' \ --header 'Authorization: Bearer auto value' \ --header 'Accept: */*' \ --header 'Host: localhost:9000' \ --header 'Connection: keep-alive' \ --header 'Cookie: user_id=12345'
响应内容:
上图中,此时,我们能够正常传递 Cookie 和 Authorization 头字段了。
注意:
(1)根据你的应用需求,你可能需要添加或移除某些头信息作为敏感头。
(2)确保不要将不应该被视为敏感的头信息错误地添加到 sensitive-headers 中,因为这可能会影响日志记录和调试的便利性。
点击下载/查看本教程相关资料或者源代码。