前言

此问题于2017年9月29日发现,至今(2017年10月19日)七牛文档仍未进行修复,故发此文,希望引起七牛官方重视。

前些日子项目需要,用上七牛对象存储,因之前都是用的传统架构:

  1. 客户端 -> 业务服务器 -> 七牛云

这次打算换一下,尝试更节省业务服务资源的直传对象存储方式:

  1. 客户端 -> 业务服务器拿 Token
  2. 客户端 -> 直传七牛云
  3. 七牛云 -> 回调业务服务器 HTTP API 接口
  4. 业务服务器收到上传通知, 验证来自七牛服务器 -> done.

Just like this:

Refer to: Qiniu PHP SDK Document
Refer to: Qiniu PHP SDK Document

过程

由此,过程中有必不可少的一环:验证回调请求是来自于七牛的服务器,而不是其他的伪装/恶意请求。

故寻找七牛文档:

  1. 第一条链接压根没提到验证回调的问题。(难道七牛的 PHP 工程师压根忽略了这个安全问题么?)
  2. 第二条链接内同样不存在相关解答。
  3. 终于,在第三条链接的末尾找到了关于这个问题的解答:

“值得庆幸的是”,有 PHP 的代码实现。

但我们那时候还高兴的太早了。

排查

接下来我们使用此函数来验证权限,但经过多轮调试,无论如何都无法验证通过。最开始我以为是潘昭宇代码没有认真看,粗心大意引起的错误,但后来我亲自看代码,一步一步检查可能的编码问题、参数问题,甚至用 Fiddler 做代理看服务器发来的数据包是否正常、XDebug 下断一步一步调试,最终发现的确是没问题的。

这就奇了怪了!为什么会出错呢?

确定我们的算法没有问题后,我们决定继续研究文档,因为那个时候我们认为这样的大厂更新了这么久的文档,怎么可能会出问题呢,有坑的话我们肯定不是第一个踩下去的人。

认真“研读”之后,我们发现:在安全机制 - 上传策略的文档内,对callbackBody的解释如下:

上传成功后,七牛云向业务服务器发送 Content-Type: application/x-www-form-urlencoded 的 POST 请求。该字段 App-Server 可以通过直接读取请求的 query 来获得,支持魔法变量和自定义变量。callbackBody 要求是合法的 url query string。如:key=$(key)&hash=$(etag)&w=$(imageInfo.width)&h=$(imageInfo.height)。

这句话有点迷,毕竟下一行的callbackBodyType是这样说的:

上传成功后,七牛云向业务服务器发送回调通知 callbackBody 的 Content-Type。默认为 application/x-www-form-urlencoded,也可设置为 application/json。

  • callbackBody 要求是合法的 url query string
  • 也可设置为application/json

按照正常思维,这应该是不受影响的,默认是 url query stirng,可以改为 json 格式。但这两句相互有所冲突的描述引起了我们的重视,遂开始动工:原本我们使用统一的 json 格式作为 callbackBody 发送到业务服务器,现尝试改为 query string 测试看会不会有问题。

经过测试,七牛的回调通过了验证……

当时的心情……!@#^@)##^@!@

我和潘昭宇调了一整天的问题,居然 TM 是因为七牛的锅。

解决

问题找到了,接下来就要解决。

遂提交工单,因为当天晚上已经深夜,我们工单提交之后就各自回家了。

第二天工单的回复,不出意外一波三折。

  • 经过两小时得到的答复:是否得到解决?
  • 再次回复后,得到的答复是文档显而易见的,答非所问。由此可见:七牛客服人员没有、或是没有认真阅读我工单最初提出的问题,直接匆忙给出了答复,再次拖慢了沟通效率。
  • 再次回复,直接附上官方文档链接,为了防止不认账我把代码也顺便贴了上去,同时把我们找到的问题关键点:callbackBodyType 参数也作了说明。
  • 终于得到一篇看起来像是有所眉目的答复:链接,发现一重要线索:居然用到了$contentType参数,这不就是 callbackBodyType 吗!虽然此文档内代码非常“简略”,就连$contentType都是写死的,但也至少给我们提供了解决思路。
  • 于是,github 下载七牛 PHP SDK 源码,果然 SDK 内有此函数实现。而以上列举的三篇文档内却从未看到一处提及。
  • 过了一会七牛官方发来 github 链接,虽然已经没什么卵用。

题外话

很巧的是,第二天有个商务人员联系我(企业账号刚注册没多久),简直求之不得啊!工单沟通成本太大,我马上提出安排几个技术人员拉了一个群一起来探讨这个问题。

接下来,我们花了大概半个小时的时间和他们解释当前的情况是怎样的,但是貌似对方并不是“真正的”后端技术人员,也联系不到技术人员,所以也没起到什么作用。

不过值得肯定的是,对方态度是非常不错的,积极配合解决。

Finally

em…

问题圆满解决,值得肯定的是,解决问题的态度还算满意,无论是电话联系的商务,还是工单,均反复承诺尽快完善,工单上的答复甚至是已经在整理文档并且进行修改。于是我们也就得过且过,继续忙其他的东西。

然而今天(2017-10-19)和潘昭宇偶然聊起来:

  • “话说最近要开新项目了,不知道七牛那边文档有没有更新?之前调了那么久的坑。”
  • “不知道啊,我看看”…… “em… 貌似… 没有……”
  • 。。。

不知道七牛官方口中的尽快是 20+天?还是技术人员整理文档整理了几个周还没写完。

幕后的原因我们不得而知,大概是我们这种创业小公司遇到的问题,dalao 们也不会放在眼里吧。

弃坑,下个项目换又拍云。

硬广:CAREERS