API Twitter 401 на / account / verify_credentials - PullRequest
2 голосов
/ 09 октября 2019

Я пытаюсь использовать твиттер 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. Поэтому я не уверен, что хуже, или какой правильный способ сделать это.

1 Ответ

3 голосов
/ 09 октября 2019

Хорошо, наконец-то все заработало

Итак, используя предложение в комментариях, я скачал почтальон и скопировал всю свою информацию в почтальон - когда я сделал запрос там, я получил 200!

Итак, я оглянулся назад и попытался выяснить, что отличалось, и было несколько вещей:

Сначала в функции знака hmac отсутствовала &

Новая функция (добавлена ​​еще одна)& после URL):

    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 разделил свои параметры на &, но все они должны были быть заменены на , - мне также нужно было окружить каждыймоих значений в ""

Так это выглядело так:

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!

Надеюсь, это поможет кому-то еще (хотя я уверен,маловероятно, учитывая, насколько специфичны эти проблемы)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...