使用新浪微博开放平台api同步微博内容至自己网站(这是第一篇:关于uploadAPI的OAuth验证失败问题(组图))
优采云 发布时间: 2021-12-31 23:32使用新浪微博开放平台api同步微博内容至自己网站(这是第一篇:关于uploadAPI的OAuth验证失败问题(组图))
新浪微博很受欢迎,开放平台很受欢迎,开发者很受欢迎。
开发者受欢迎是因为新浪微博开放平台对开发者非常不友好,其API从实现到文档都很粗糙。
API 实现不规范,可以容忍,但是文档没有解释清楚,开发者自己探索是很离谱的。新浪似乎还没有来得及照顾第三方开发者,开放平台现在只是“开门见山”。结果就是开发者折腾了很多没有意义的东西,浪费时间!
我写这一系列文章的目的是为了避免后来者犯同样的罪。
这是上传API OAuth认证失败的第一篇。去论坛搜索上传就知道有多少人受苦了。
Upload API 的 OAuth 之所以难,部分是因为它的 HTTP 请求格式的特殊性,主要是因为新浪微博的实现令人难以置信。
Upload API 的特殊性在于它的请求“使用多部分/表单数据编码提交”。根据OAuth1.0协议,Content-Type为multipart/form-data的HTTP请求的entity body不参与OAuth签名。因此,上传API的OAuth应该比其他普通API简单,因为签名只涉及OAuth参数(以oauth_开头的一系列特殊参数)。因此,标准的签名基字符串应该是:
POSThttp%3A%2F %% 2Fstatuses%2Fupload.jsonoauth_consumer_key%3Dxxxxxxxxxx%26oauth_nonce%3D798014939%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1312912324%26oauth_version%3D1312912324%26oauth_version%3D1312912324%26oauth_ytoken0
对应的标准授权头应该是:
OAuth oauth_consumer_key=xxxxxxxxxx、oauth_token=yyyyyyyyyy、oauth_signature_method=HMAC-SHA1、oauth_version=1.0、oauth_nonce=798014939、oauth_nonce=798014939、oauth_nonce=798014939、oauth_nonce=798014939、oauth33331231时间oauth_signature_method=HMAC-SHA1
但是,您会收到:
40107:Oauth 错误:signature_invalid!
这是因为新浪微博上传API的实现需要签名基串收录pic以外的参数。所以新浪微博需要的Signature Base String是这样的:
POSThttp%3A%2F%%2Fstatuses%2Fupload.jsonlat%3D37.78711200%26long%3D-122.40846000%26oauth_consumer_key%3Dxxxxxxxxxx%26oauth%258oth%258oth%26588oth%268588888888888885 _signature_method3 26oauth_timestamp%3D1312912886%26oauth_token%3Dyyyyyyyyyy%26oauth_version%3D1.0%26status%3DPic
问题出在这里:status、lat、long参数是在entity body中提交的。如前所述,它们不参与 OAuth 签名。为了符合 OAuth 协议,必须将这些参数添加到 URL 查询字符串或 Authorization 标头中。
规范的开发者这样做了,结果“错了”。新浪微博服务器依旧返回:
40107:Oauth 错误:signature_invalid!
其实不管怎么折腾,只要遵循OAuth协议,肯定是甩不掉的,因为新浪微博不遵循OAuth协议。
对于 Content-Type 为 multipart/form-data 的 HTTP 请求,新浪微博要求非二进制参数(如上传 API 中的 pic 参数)参与 OAuth 签名,并且还要求这些参数是“非原创的” ”。换句话说,Signature Base String 必须收录这些参数,但这些参数不能出现在 URL 查询字符串或 Authorization 标头中。这意味着新浪微博服务器收到请求后,会从实体主体中提取这些参数进行OAuth签名验证。再一次,对于 Content-Type 是 multipart/form-data 的 HTTP 请求,这违反了 OAuth 协议。但是在新浪微博上,我们必须违反OAuth协议才能通过OAuth验证。
即使你不考虑像我这样费时费力的探索过程,新浪微博的非标准实现也给开发者带来了很多麻烦,因为它导致了很多OAuth库的追随OAuth 协议无法直接使用。
在折腾的过程中,我还发现了另一个可怕的bug。如果pic的Content-Disposition头部缺少filename参数,新浪微博也会返回“40107:Oauth Error:signature_invalid!”,虽然pic和OAuth没有关系,虽然按照标准是不需要filename的,但实际上文件名在此处没用。
最后总结一下获取新浪微博上传API的“正确”方式:
所有参数均以 multipart/form-data 格式提交,不能出现在 URL 查询字符串或 Authorization 标头中。除 pic 外的所有参数都输入 Signature Base String 以参与 OAuth 签名。 pic 的 Content-Disposition 头必须收录 filename 参数。
官方论坛帮助不大,哭了很多,但是省的少。未做UTF-8编码或URL编码导致OAuth认证失败是开发者自身的错。本文也适用于其他使用 multipart/form-data 编码提交 HTTP 请求的 API,例如 update_profile_image。
转载原文