Я пытаюсь использовать твиттер API, и настраиваю обработчик для обработки твиттеров API-запросов.
Для этого я использую HTTPUrlConnection
и следую за API твиттера
Мне удалось пройти проверку подлинности с использованием 3-стороннего процесса OAuth, но я застрял при попытке сделать запрос с помощью маркера oauth.
Вот пример того, как выглядят мои заголовки аутентификациинапример:
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_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, полученным от/oauth/access_token
После того, как я позвоню, я получу 400: Bad Request
Есть ли что-то очевидное, что я делаю не так?
Обновление: установивпараметры в конце URL-адреса, такие как ?key=value&key2=value2...
вместо 400, я получаю 401. Поэтому я не уверен, что хуже, или какой правильный способ сделать это.