401 Требуется авторизация по запросу Twitter API - PullRequest
0 голосов
/ 30 октября 2018

Я создаю скрипт Python для автоматической публикации обновлений статуса в Twitter. Я внимательно прочитал и следовал документации API для создания подписи и выполняю запрос на обновление статуса. Но я получаю сообщение об ошибке при выполнении запроса.

HTTP Error 401: Authorization Required

Я видел больше подобных вопросов в Stackoverflow и других ресурсах, но пока не смог найти решение этой проблемы.

 def sendTweet(self):

      url = 'https://api.twitter.com/1.1/statuses/update.json'
      message = 'Testing'

      oauths = [
            ['oauth_consumer_key', '1234567890'],
            ['oauth_nonce', self.generate_nonce()],
            ['oauth_signature', ''],
            ['oauth_signature_method', 'HMAC-SHA1'],
            ['oauth_timestamp', str(int(time.time()))],
            ['oauth_token', '1234567890'],
            ['oauth_version', '1.0']
        ]

        signature = self.sign(oauths, message)
        oauths[2][1] = signature

        count = 0
        auth = 'OAuth '
        for oauth in oauths:
            count = count + 1
            if oauth[1]:
                auth = auth + self.quote(oauth[0]) + '="' + self.quote(oauth[1]) + '"'
            if count < len(oauths):
                auth = auth + ', '

        headers = {
            'Authorization': auth,
            'Content-Type': 'application/x-www-form-urlencoded'
        }

        payload = {'status' : message.encode('utf-8')}

        req = urllib2.Request(url, data=urllib.urlencode(payload), headers=headers)

        try:
            response = urllib2.urlopen(req)
            data = response.read()
            print data
        except (urllib2.HTTPError, urllib2.URLError) as err:
            print err

Это то, что делает функция self.sign

def sign(self, oauths, message):

        signatureParams = ''
        count = 0

        values = [
            ['oauth_consumer_key', oauths[0][1]],
            ['oauth_nonce', oauths[1][1]],
            ['oauth_signature_method', oauths[3][1]],
            ['oauth_timestamp', oauths[4][1]],
            ['oauth_token', oauths[5][1]],
            ['oauth_version', oauths[6][1]],
            ['status', message]
        ]

        customerSecret = '1234567890'
        tokenSecret = '1234567890'

        for value in oauths:
            count = count + 1
            signatureParams = signatureParams + self.quote(value[0]) + '=' + self.quote(value[1])
            if count < len(oauths):
                signatureParams = signatureParams + '&'

        signature = 'POST&' + self.quote(self.endPoint) + '&' + self.quote(signatureParams)
        signinKey = self.quote(customerSecret) + '&' + self.quote(tokenSecret)

        signed = base64.b64encode(self.signRequest(signinKey, signature))

        return signed

И ниже вспомогательные функции.

def generate_nonce(self):
    return ''.join([str(random.randint(0, 9)) for i in range(8)])

def quote(self, param):
    return urllib.quote(param.encode('utf8'), safe='')

def signRequest(self, key, raw):
    from hashlib import sha1
    import hmac
    hashed = hmac.new(key, raw, sha1)
    return hashed.digest().encode('base64').rstrip('\n')

Вот так выглядит строка auth, когда я ее печатаю.

OAuth oauth_consumer_key="1234567890",
oauth_nonce="78261149",
oauth_signature="akc2alpFWWdjbElZV2RCMmpGcDc0V1d1S1B3PQ%3D%3D",
oauth_signature_method="HMAC-SHA1", oauth_timestamp="1540896473",
oauth_token="1234567890",
oauth_version="1.0"

Это точно так же, как и должно быть, если я читаю документацию в Твиттере. Но все равно я получаю ошибку 401 Authorization Required. Я просто не вижу, что здесь происходит не так.

Уровень доступа для ключей Read, write, and direct messages

Все ключи заменены на 1234567890, но в реальном коде я использую настоящие.

Кто-то имеет представление о том, что я делаю неправильно? Заранее спасибо!

...