最佳实践
API网关灰度发布最佳实践
灰度发布是指在API的新、旧版本间平滑过渡的一种发布方式。用户在应用迭代过程中会不断有新的API版本发布,在新版本发布之前,可使用灰度流量控制进行小规模验证。API网关支持配置不同的后端服务,按照多种策略进行匹配转发,轻松解决企业应用的灰度发布,环境管理等难题。
基于HTTP请求内的用户参数进行灰度
当Query、Cookie、Header 中存在和用户身份直接相关的参数时,我们就可以直接利用该请求参数转发请求到不同的后端服务。比如对高级用户优先体验新版本,获取用户体验建议,并降低版本升级的风险,并可以参考以下说明进行配置。
操作步骤:
(1)创建API分组,后端服务源选择“负载均衡”,此时支持添加多个后端服务。
(2)勾选“启动灰度”,选择按内容进行策略设置。
(3)基于query位置,通过userlevel匹配不同值,将流量分到不同的后端服务,当userlevel为1时,分配到后端旧版本;当userlevel为2时,分配到后端新版本。
配置基于HTTP请求中query的灰度策略页面如下图所示。
针对特定访问IP(段)进行灰度
可以利用不同的请求源IP地址段分配请求到不同的后端服务,从而实现灰度发布。
场景一:当一些服务内测时,需要在测试环境和生产环境中访问不同版本的后端服务。
场景二:不同地区的用户访问不同的后端服务,实现就近访问。
操作步骤如下所示。
(1)创建API分组,后端服务源选择“负载均衡”,此时支持添加多个后端服务。
(2)勾选“启动灰度”,选择按内容进行策略设置。
(3)规则类型选择IP,选择不同服务输入不同IP(段)值。完全匹配10.1.2.3的分配到测试环境服务,完全匹配10.2.1.3的分配到生产环境服务。
API调试与访问控制最佳实践
- Basic-Auth访问控制方式的API接口调试使用说明
- JWT访问控制方式的API接口调试使用说明
- OAuth2访问控制方式的API接口调试使用说明
- HMAC-Auth 访问控制方式的API接口调试使用说明
API支持四种访问控制方式:无认证、Basic-Auth、JWT、OAuth2、HMAC-Auth。其中无认证类型为授权后不需要任何凭证即可调用;其他认证类型在授权后仍然需要相应类型的访问凭证方可成功调用。
Basic-Auth
本示例使用的test0628 Api访问控制类型为Basic-Auth。
正常调用示例
(1) 通过创建的API绑定访问控制插件basic-auth来实现,查看API详情可知。
(2) 已将API经过授权流程授权给应用(授权状态为通过的)。
(3) 在该应用中添加Basic-Auth类型的访问凭证,使用已添加对应认证类型(本示例为Basic-Auth)的访问凭证。
(4) 通过BASE64加密工具,对使用basic auth认证类型凭证的用户名和密码(格式:用户名:密码))进行BASE64加密,如下图所示。
(5) 进入调试页面(API详情页面/应用详情页面),使用如上生成的base64值,作为Authorization headers参数值(格式:Basic base64),可以看到已经调试通过正常返回接口数据。或者直接赋值用户名和密码。
非正常调用示例
(1) 调试时未添加相应凭证认证header时,接口返回显示”invalid authentication credentials“。
(2) 使用错误的认证header时(已授权的consumer下没有这样的凭证),接口返回显示”invalid authentication credentials“。
JWT
本示例以API“showcase0608”为例,访问控制类型为JWT。
正常调用示例
(1) 通过创建的API绑定访问控制插件JWT来实现,查看API详情可知。
(2) 已将API经过授权流程授权给应用(授权状态为通过的)。
(3) 在该应用中添加JWT类型的访问凭证,使用已添加对应认证类型(本示例为JWT类型,算法HS256)的访问凭证。
(4) 通过工具,对使用JWT认证类型凭证生成JWT token,测试时使用如图所示工具(iss参数对应key),并复制右侧token信息。
(5) 进入调试页面(API详情页面/应用详情页面),用token作为Authorization headers参数值(格式:Bearer token),返回结果显示”hello“。
(6)或使用jwt参数传入key和secret值,返回结果显示”hello“。
非正常调用示例
未传入token 时接口将不能正常访问,返回结果显示”{"message":"unauthorized"}“。
java程序中生成 jwt token
(1) 添加jwt依赖。
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
(2) 生成代码。
public static void main(String[] args) {
String jwt = Jwts.builder()
.setHeaderParam("typ","jwt")
.setHeaderParam("alg","HS256")
.setIssuer("1b0LTrhrJich1pTBD8q24KCHB6HNjQiY") //key
.signWith(SignatureAlgorithm.HS256, Base64.getEncoder().
encodeToString("Xkuw9HIyMks0ohN86u8TjdBtc0sV8dF9"// secret
.getBytes(Charset.forName("utf-8"))))
.compact();
System.out.println(jwt);
}
(3) 输出信息
eyJ0eXAiOiJqd3QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIxYjBMVHJockppY2gxcFRCRDhxMjRLQ0hCNkhOalFpWSJ9.hfXgg4faqNxjsOBSPt0uHghaErwDSd
exR6ONiG6Dqpc
OAuth2
本示例以testfourapi为例,访问控制类型为OAuth2。
正常调用示例
通过创建的API绑定访问控制插件JWT来实现, 查看API详情可知。
已将API经过授权流程授权给应用(授权状态为通过的)。
在该应用中添加OAuth2类型的访问凭证,使用已添加对应认证类型(本示例为 OAuth2类型,授权方式client credential)的访问凭证。
(1) 进入调试页面(API详情页面/应用详情页面),用token作为Authorization headers参数值(格式:Bearer token)。
(2) 或使用oauth2参数传入clientId和clientSecret值。
HMAC-Auth
本示例以testfiveapi为例,访问控制类型为HMAC-Auth。
正常调用示例
(1)通过API详情中绑定插件tab中的绑定访问控制插件,绑定HMAC-Auth的插件,查看API详情可知。
(2) 已将API经过授权流程授权给应用。
(3) 在该应用中添加hmac-auth类型的访问凭证,使用已添加对应认证类型(本示例为hmac-auth类型)的访问凭证。
(4) 在hmac-auth的signature的算法说明:
Signature =base64(HMAC-SHA1(<signing_string>, "secret"),"US-ASCII")
a. 获取GMT时间。
b. 拼接date时间和需要签名的其他属性信息,中间以空格分隔,例如
String content = stb.append("x-date: ").append(hdate).append("\n").append("hello: ").append(queryParam).toString()。
c. 根据签名的加密算法进行加密,例如HmacSHA1("内容","秘钥")。
d. 加密内容Base64转换成"US-ASCII"字符类型。
signing_string="date: Thu, 22 Jun 2017 17:15:21 GMT\nGET /requests HTTP/1.1"
digest=HMAC-SHA256(signing_string, "secret") base64_digest=base64(digest)</node>
如果签名需要digest信息,则signature的加密content信息,需要加上digest信息例如:<node>
stb.append("date:").append(date).append("\n").append("digest: ").append("SHA-256=").append(digest).toString();
(5) 在hmac-auth的signature的java说明demo。
public static void main(String[] args) {
Date d=new Date();
DateFormat format=new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
format.setTimeZone(TimeZone.getTimeZone("GMT"));
String hdate = format.format(d);
log.info("date: {}",hdate);
String secret = "LSlmVwKVCu0ZGY7ZOvLM0gW5XUbwewY4"; //用户的密钥
StringBuilder stb = new StringBuilder();
String content1 = stb.append("date: ").append(hdate).toString();
log.info("签名前内容: "+content1);
try {
String signature2 = new String(Base64.getEncoder().encode(HmacSha1Util.signatureReturnBytes(content1, secret)),"US-ASCII");
log.info("指定编码2: {}", signature2);
} catch (Exception e) {
e.printStackTrace();
}
}
(8) 进入调试页面(API详情页面/应用详情页面),header中添加date和authorization。
hmac+空格+username=”username”,+空格+algorithm=”签名算法”,+空格+headers=”签名属性”,+空格+signature="签名内容"。例如下面这段:Authorization: hmac username="alice123", algorithm="hmac-sha256", headers="date", signature="ujWCGHeec9Xd6UD2zlyxiNMCiXnDOWeVFMu5VeRUxtw="