我发现了大厂OpenApi接口的bug!你发现了吗?

2024年 5月 20日 34.3k 0

本文记录我在对接字节旗下产品火山云游戏OpenApi 接口文档时遇到的坑,希望能帮助大家(火山云旗下云游戏产品的文档坑很多,我算是从零到一都踩了一遍,特此记录,希望大家引以为鉴)。

1. 文档问题

很经典的开局一张图,对接全靠问。

我发现了大厂OpenApi接口的bug!你发现了吗?-1产品给的图

这里给大家强调下,当要跟第三方产品对接时,一定要确认拿到的文档是不是最新版本。

比如我在这次对接中,第一次拿到的文档是产品给的,在业务中需要用到一个用户主动退出游戏的接口,于是我在第一份文档里面找到一个用户退出游戏的接口 RomoveUser。

我发现了大厂OpenApi接口的bug!你发现了吗?-2RemoveUser

但是当我在控制台调用此接口报错后,去群里一问才发现,对方建议我使用官网公布的最新接口文档。

官网最新文档:https://www.volcengine.com/docs/6512/143674

进入官网发现 RemoveUser 这个接口已经是历史接口了,官方建议换到 BanRoomUser 接口。

我发现了大厂OpenApi接口的bug!你发现了吗?-3BanRoomUser

OK,这里算是踩到了第一个坑,文档版本不是最新。

ps:还要说一下,火山云旗下云游戏的这个 OpenApi 接口文档需要在群里联系他们开白才能看到,说实话给我的感觉很奇怪,怀疑产品是否有赶鸭子上架问题,暂且怀疑他们的目的是防止不明攻击吧。

2. OpenApi 示例 demo

第三方接口的接入一般都需要做鉴权。火山云旗下云游戏产品的 OpenApi 接口接入当然也不例外。于是我开始了第二个踩坑之旅,那就是他们给出的 OpenApi 示例 demo 的使用过于简单。

我发现了大厂OpenApi接口的bug!你发现了吗?-4图片

火山云旗下云游戏产品的 OpenApi 示例 demo 写的很简单,只提供了一个 GET 请求示例。

OpenApi 示例 demo 地址:https://github.com/volcengine/veGame

但是在我司的业务场景还是上个问题,需要一个用户主动退出游戏的接口,在火山云官网的 OpenApi 文档中我也找到了这个接口,就是上文提到的 BanRoomUser 接口。

但是在官方文档中 BanRoomUser 接口是一个 POST JSON 格式的请求。官方给出的 OpenApi 示例 demo 中并没有关于 POST JSON 请求的示例代码,所以只能靠我一个人查看他们提供的 SDK 依赖源码硬猜来写...,这就很让人头痛了。

好在我翻阅他们 SDK 源码中找到一个靠谱的 json(...) 请求方法,来完成这个 POST JSON 请求。

我发现了大厂OpenApi接口的bug!你发现了吗?-5图片

OK,说干就干,直接写好示例代码,开始发送 POST JSON 请求。

我发现了大厂OpenApi接口的bug!你发现了吗?-6错误返回

what f**k?什么鬼,返回了我一个 null,此时我的内心中充满了一个大大的问号。

我开始怀疑我的代码是不是写错了。但是当我经历过数次源码 debug 以及调用其他 OpenApi 接口测试并得到正确返回后,我坚定的认为我没错,这就是火山云 OpenApi 的 bug!

我发现了大厂OpenApi接口的bug!你发现了吗?-7正常返回

OK,说干就干,直接反馈给火山那边。

接着火山那边的人就联系说下午两点开会一起远程共享我的屏幕看看,OK 欣然接收,让他们见证下他们写的 bug!

...

时间来到下午两点,当我共享屏幕给字节工程师演示这个 bug 时,我的控制台打印如下:

我发现了大厂OpenApi接口的bug!你发现了吗?-2图片

woca,竟然不是 null!好在我脑袋灵活,思路清晰,瞬间想到我改了一个参数 GameId,之前返回 null 时,我传的 GameId 是一个假数据,现在我传的是一个真数据。造成了返回不一致。

OK,找到了返回正常的原因,当我把 GameId 改成假数据时,如我所愿,返回了一个 null。

我发现了大厂OpenApi接口的bug!你发现了吗?-3图片

自此,我也就在字节工程师的围观下,复现了他们的 OpenApi 接口的线上 bug。大功告成。

3. 鉴权失败

字节提供的 OpenApi 示例 demo 现在算是跑通了,但是由于我司项目一些依赖限制问题,我们不能直接引入火山云旗下云游戏产品的 SDK 依赖。所以我还得手动编写生成签名的代码。于是我开始了第三个踩坑之旅,那就是 GET 请求验签成功 POST 请求验签失败的问题。

这里先说一下,火山云提供了手动生成签名的示例代码:

我发现了大厂OpenApi接口的bug!你发现了吗?-4图片

Java 生成签名的代码:https://github.com/volcengine/volc-openapi-demos/blob/main/signature/java/Sign.java

这里我也是直接把签名代码拿来即用就行,一开始接入生成签名代码非常顺利,GET 请求的 OpenApi 接口都是可以顺利调通的,但是当我调用 BanRoomUser 接口时(没错,又是这个接口,踩的三个坑都与这个接口有关),直接提示验签失败!

我发现了大厂OpenApi接口的bug!你发现了吗?-5验签失败

OK,开始排查为什么签名失败。

我发现了大厂OpenApi接口的bug!你发现了吗?-6图片

查看源码发现,POST JSON 请求时的 contentType 还是 application/x-www-form-urlencoded,直觉告诉我这里不对,所以改成 application/json 试试,看看控制台返回,

我发现了大厂OpenApi接口的bug!你发现了吗?-7图片

很好,还是验签失败!!!

我尽力了兄弟们,这个坑踩的我是无话可说。直接联系直接字节开发人员看下我的请求内容是哪里有问题。

在与字节开发人员一起观摩我写的代码以及生成的签名之后,大家都没找到问题所在。那没办法了,只能上服务器看接口请求日志了。

我发现了大厂OpenApi接口的bug!你发现了吗?-8图片

大家可以看出问题在哪里吗?没错我刚刚不是把 contentType 改成了 application/json 吗,为什么日志显示的 contentType 是 application/json; !。

OK,到这里问题也找到了,原因是我这个项目用的 http 请求工具是 okhttp3。他自动给我拼接上去的!

那么怎么解决嘞,替换 http3 工具的话,改造成本比较大,所以我就顺势把代码的 contentType 也改成application/json; charset=utf-8。

在测试一遍,看看控制台打印。

我发现了大厂OpenApi接口的bug!你发现了吗?-9图片

OK,拿到成功响应,自此也就解决了第三个坑,POST JSON 请求时的验签不匹配问题。

最后给大家贴出手动生成验签的代码,有需要自取。

@Slf4j
public class Sign {
private static final BitSet URLENCODER = new BitSet(256);
private static final String CONST_ENCODE = "0123456789ABCDEF";
public static final Charset UTF_8 = StandardCharsets.UTF_8;
private final String region;
private final String service;
private final String host;
private final String path;
private final String ak;
private final String sk;
static {
int i;
for (i = 97; i

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论