我发现了字节OpenApi接口的bug!
本文记载我在对接字节旗下产品火山云旗下云游戏产品 OpenApi 接口文档时碰到的坑,盼望能资助大家(火山云旗下云游戏产品的文档坑很多,我算是从零到一都踩了一遍,特此记载,盼望大家引以为鉴)。1. 文档问题
很经典的开局一张图,对接端赖问,
https://img2024.cnblogs.com/blog/3151081/202405/3151081-20240516171816373-46803801.png
https://img2024.cnblogs.com/blog/3151081/202405/3151081-20240516171822278-1210717289.png
这里给大家夸大下,当要跟第三方产品对接时,一定要确认拿到的文档是不是最新版本。
比如我在这次对接中,第一次拿到的文档是产品给的,在业务中必要用到一个用户主动退出游戏的接口,于是我在第一份文档里面找到一个用户退出游戏的接口 RomoveUser。
https://img2024.cnblogs.com/blog/3151081/202405/3151081-20240516171829348-599973481.png
但是当我在控制台调用此接口报错后,去群里一问才发现,对方建议我使用官网公布的最新接口文档。
官网最新文档:https://www.volcengine.com/docs/6512/143674
进入官网发现 RemoveUser 这个接口已经是历史接口了,官方建议换到 BanRoomUser 接口。
https://img2024.cnblogs.com/blog/3151081/202405/3151081-20240516171834795-1824851544.png
OK,这里算是踩到了第一个坑,文档版本不是最新。
ps:还要说一下,火山云旗下云游戏的这个 OpenApi 接口文档必要在群里接洽他们开白才气看到,说实话给我的感觉很奇怪,猜疑产品是否有赶鸭子上架问题,临时猜疑他们的目的是防止不明攻击吧。
2. OpenApi 示例 demo
第三方接口的接入一样平常都必要做鉴权。火山云旗下云游戏产品的 OpenApi 接口接入固然也不例外。于是我开始了第二个踩坑之旅,那就是他们给出的 OpenApi 示例 demo 的使用过于简单。
https://img2024.cnblogs.com/blog/3151081/202405/3151081-20240516171841298-1248114327.png
火山云旗下云游戏产品的 OpenApi 示例 demo 写的很简单,只提供了一个 GET 请求示例。
OpenApi 示例 demo 地址:https://github.com/volcengine/veGame
但是在我司的业务场景还是上个问题,必要一个用户主动退出游戏的接口,在火山云官网的 OpenApi 文档中我也找到了这个接口,就是上文提到的 BanRoomUser 接口。
但是在官方文档中 BanRoomUser 接口是一个 POST JSON 格式的请求。官方给出的 OpenApi 示例 demo 中并没有关于 POST JSON 请求的示例代码,以是只能靠我一个人查看他们提供的 SDK 依靠源码硬猜来写...,这就很让人头痛了。
好在我翻阅他们 SDK 源码中找到一个靠谱的 json(...) 请求方法,来完成这个 POST JSON 请求。
https://img2024.cnblogs.com/blog/3151081/202405/3151081-20240516171847669-67874795.png
OK,说干就干,直接写好示例代码,开始发送 POST JSON 请求,
https://img2024.cnblogs.com/blog/3151081/202405/3151081-20240516171855626-1780070912.png
what f**k?什么鬼,返回了我一个 null,此时我的内心中充满了一个大大的问号。
https://img.soogif.com/tZB3qhTIgXwQSB1tVDVJVOWJb3lhLVxx.gif?scope=mdnice
我开始猜疑我的代码是不是写错了。但是当我经历过数次源码 debug 以及调用其他 OpenApi 接口测试并得到准确返回后,我刚强的认为我没错,这就是火山云 OpenApi 的 bug!
https://img2024.cnblogs.com/blog/3151081/202405/3151081-20240516171910095-1429086138.png
OK,说干就干,直接反馈给火山那边。
https://img2024.cnblogs.com/blog/3151081/202405/3151081-20240516171921482-1432085470.png
接着火山那边的人就接洽说下战书两点开会一起远程共享我的屏幕看看,OK 欣然吸收,让他们见证下他们写的 bug!
...
时间来到下战书两点,当我共享屏幕给字节工程师演示这个 bug 时,我的控制台打印如下,
https://img2024.cnblogs.com/blog/3151081/202405/3151081-20240516171926806-166776992.png
woca,竟然不是 null!好在我脑袋灵活,思路清晰,刹时想到我改了一个参数 GameId,之前返回 null 时,我传的 GameId 是一个假数据,如今我传的是一个真数据。造成了返回不一致。
OK,找到了返回正常的缘故原由,当我把 GameId 改成假数据时,如我所愿,返回了一个 null。
https://img2024.cnblogs.com/blog/3151081/202405/3151081-20240516171931638-277798465.png
自此,我也就在字节工程师的围观下,复现了他们的 OpenApi 接口的线上 bug。大功告成。
3. 鉴权失败
字节提供的 OpenApi 示例 demo 如今算是跑通了,但是由于我司项目一些依靠限制问题,我们不能直接引入火山云旗下云游戏产品的 SDK 依靠。以是我还得手动编写生成签名的代码。于是我开始了第三个踩坑之旅,那就是 GET 请求验签成功 POST 请求验签失败的问题。
这里先说一下,火山云提供了手动生成签名的示例代码
https://img2024.cnblogs.com/blog/3151081/202405/3151081-20240516171936687-1059464386.png
Java 生成签名的代码:https://github.com/volcengine/volc-openapi-demos/blob/main/signature/java/Sign.java
这里我也是直接把签名代码拿来即用就行,一开始接入生成签名代码非常顺利,GET 请求的 OpenApi 接口都是可以顺利调通的,但是当我调用 BanRoomUser 接口时(没错,又是这个接口,踩的三个坑都与这个接口有关),直接提示验签失败!
https://img2024.cnblogs.com/blog/3151081/202405/3151081-20240516171940854-1172822519.png
OK,开始排查为什么签名失败。
https://img2024.cnblogs.com/blog/3151081/202405/3151081-20240516171946532-705391977.png
查看源码发现,POST JSON 请求时的 contentType 还是 application/x-www-form-urlencoded,直觉告诉我这里不对,以是改成 application/json 试试,看看控制台返回,
https://img2024.cnblogs.com/blog/3151081/202405/3151081-20240516171950615-1476314109.png
很好,还是验签失败!!!
我尽力了兄弟们,这个坑踩的我是无话可说。直接接洽直接字节开发人员看下我的请求内容是哪里有问题。
在与字节开发人员一起观摩我写的代码以及生成的签名之后,大家都没找到问题所在。那没办法了,只能上服务器看接口请求日志了。
https://img2024.cnblogs.com/blog/3151081/202405/3151081-20240516171955062-2032599836.png
大家可以看出问题在哪里吗?没错我刚刚不是把 contentType 改成了 application/json 吗,为什么日志表现的 contentType 是 application/json; charset=utf-8!。
OK,到这里问题也找到了,缘故原由是我这个项目用的 http 请求工具是 okhttp3。他自动给我拼接上去的!
那么怎么解决嘞,更换 http3 工具的话,改造成本比较大,以是我就顺势把代码的 contentType 也改成
application/json; charset=utf-8。
在测试一遍,看看控制台打印。
https://img2024.cnblogs.com/blog/3151081/202405/3151081-20240516172000326-299257918.png
OK,拿到成功响应,自此也就解决了第三个坑,POST JSON 请求时的验签不匹配问题。
末了给大家贴出手动生成验签的代码,有必要自取。
@Slf4jpublic 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
页:
[1]