我试图利用twitter api,并设置一个处理程序来处理twitter api请求。
为此,我使用HTTPUrlConnection
并关注Twitter api文档
我已经设法通过三足式OAuth流程进行身份验证,但是在尝试使用oauth令牌进行请求时却陷入困境。
以下是我的auth标头的示例:
Accept=*/*,
Connection=close,
User-Agent=OAuth gem v0.4.4,
Content-Type=application/x-www-form-urlencoded,
Authorization=
OAuth oauth_consumer_key=****&
oauth_nonce=bbmthpoiuq&
oauth_signature=*****%3D&
oauth_signature_method=HMAC-SHA1&
oauth_timestamp=1570586135&
oauth_token=*****&
oauth_version=1.0,
Host=api.twitter.com
对于auth标头中的每个标头,我将其添加到HTTP GET
调用中,如下所示:
urlConnection.setRequestProperty(header.key, header.value)
请注意,Authorization
指向一个字符串
OAuth oauth_consumer_key=****&oauth_nonce=bbmthpoiuq&oauth_signature=*****%3Doauth_signature_method=HMAC-SHA1oauth_timestamp=1570586135&oauth_token=*****&oauth_version=1.0,Host=api.twitter.com
以下参数收集如下:
oauth_consumer_key
是我的应用程序API密钥
oauth_signature
由下面的hmacSign
函数计算
oauth_token
是在/oauth/access_token
hmacSign
函数:
private fun hmacSign(requestType: RequestType, url: String, params: Map<String, String>): String {
val type = "HmacSHA1"
val key = "$API_SECRET&$tokenSecret"
val value = makeURLSafe("${requestType.string}&$url${getURLString(params.toList().sortedBy { it.first }.toMap())}")
val mac = javax.crypto.Mac.getInstance(type)
val secret = javax.crypto.spec.SecretKeySpec(key.toByteArray(), type)
mac.init(secret)
val digest = mac.doFinal(value.toByteArray())
return makeURLSafe(Base64.encodeToString(digest, NO_WRAP))
}
private fun makeURLSafe(url: String) : String {
return url.replace("/", "%2F")
.replace(",", "%2C")
.replace("=", "%3D")
.replace(":", "%3A")
.replace(" ", "%2520")
}
protected fun getURLString(params: Map<String, Any>) : String {
if (params.isEmpty()) return ""
return params.toList().fold("?") { total, current ->
var updated = total
updated += if (total == "?")
"${current.first}=${current.second}"
else
"&${current.first}=${current.second}"
updated
}
}
在我所指的GET
呼叫中,tokenSecret
是从/oauth/access_token
收到的oauth机密
拨打电话后,我得到一个400: Bad Request
有什么明显的地方我做错了吗?
更新:通过将参数放在?key=value&key2=value2...
之类的url末尾而不是400处,我得到401。所以我不确定哪个更糟,或者哪个是正确的方法。
答案 0 :(得分:3)
好的,终于可以正常工作了
因此,使用注释中的建议,我下载了邮递员,并将我的所有信息复制到邮递员中-当我在那里提出请求时,我得到了200分!
然后我回头试图找出有什么不同,并且有几件事:
首先,hmac符号函数缺少&
新功能(在网址后添加了另一个&
)
private fun hmacSign(requestType: RequestType, url: String, params: Map<String, String>): String {
val type = "HmacSHA1"
val key = "$API_SECRET&$tokenSecret"
val value = makeURLSafe("${requestType.string}&$url&${getURLString(params.toList().sortedBy { it.first }.toMap())}")
val mac = javax.crypto.Mac.getInstance(type)
val secret = javax.crypto.spec.SecretKeySpec(key.toByteArray(), type)
mac.init(secret)
val digest = mac.doFinal(value.toByteArray())
return makeURLSafe(Base64.encodeToString(digest, NO_WRAP))
}
接下来,我注意到auth标头的参数用&
分隔,但是应该用,
替换它们-我还需要将""
中的每个值都包围起来< / p>
它看起来像:
OAuth oauth_consumer_key="****",oauth_nonce="bbmthpoiuq",oauth_signature="*****%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1570586135",oauth_token="*****",oauth_version="1.0",Host="api.twitter.com"
这些更改之后,我开始获得200!
希望这对其他人有帮助(尽管我不确定考虑这些问题的具体程度不太可能)