2

Вопрос по python – Получение токена запроса из API Twitter с помощью Python 3

Я пытаюсь использовать Python 3 для взаимодействия с API Twitter, чтобы вернуть ссылку на страницу, которая дает мне пин-код, который можно использовать для запроса токенов доступа. Как подробно здесь:https://dev.twitter.com/docs/auth/pin-based-authorization

API Твиттера отвечает мне, что я не правильно авторизовал свой запрос POST, возвращая 401. Лучше всего предположить, почему я неправильно кодирую подпись HMAC в base64. Все остальные части POST-запроса, которые я генерирую, выглядят корректно на основе примеров правильных POST-запросов, которые я рассмотрел.

Я потратил несколько дней, работая над этим, и я надеюсь, что кто-то может помочь подтолкнуть меня к финальной части.

Вот самые важные части документации по API Twitter:https://dev.twitter.com/docs/api/1/post/oauth/request_token

https://dev.twitter.com/docs/auth/authorizing-request

Это код, который я использую:

import urllib.parse, urllib.request, json
from hashlib import sha1
import hmac
import binascii
import time
import random
import sys

#Server Links
REQUEST_URL = "https://api.twitter.com/oauth/request_token";
ACCESS_URL = "https://api.twitter.com/oauth/access_token";
AUTHORIZE_URL = "https://api.twitter.com/oauth/authorize";

#Consumer keys
TOKEN = "Omitted"
TOKEN_SECRET = "Omitted"

#Access keys
ACCESS_TOKEN = ""
ACCESS_TOKEN_SECRET = ""

TWEET = ""

count = 1

while len(sys.argv) > count:
    TWEET += sys.argv[count] + " "
    count += 1

TWEET = TWEET[:-1] #Get rid of trailing space

print(TWEET + "\n")

#Build content header for POST to return request tokens

HEADER_TITLE = "Authorization:"

#Consumer key
HEADER = 'OAuth oauth_callback="oob" oauth_consumer_key="' + TOKEN + '", '

#Nonce
HEADER += 'oauth_nonce="'
NONCE = ""
for i in range(32):
    NONCE += chr(random.randint(97, 122))
HEADER += NONCE
HEADER += '", '

#Timestamp
TIMESTAMP = str(int(time.time()))

#Signature
HEADER += 'oauth_signature="'
PARAMETER_STRING = "include_entities=true&oauth_consumer_key=" + TOKEN + "&oauth_nonce=" + NONCE + "&oauth_signature_method=HMAC-SHA1&oauth_timestamp=" + TIMESTAMP + "&oauth_version=1.0"
BASE_STRING = 'POST&' + urllib.parse.quote(REQUEST_URL, '') + '&' + urllib.parse.quote(PARAMETER_STRING, '')
SIGNING_KEY = urllib.parse.quote(TOKEN_SECRET, '') + '&'
print("DEBUG : SIGNING KEY " + SIGNING_KEY + " BASE STRING " + BASE_STRING + "\n")
HEADER += str(binascii.b2a_base64(hmac.new(BASE_STRING.encode(), SIGNING_KEY.encode(), sha1).digest()[:-1]))#Note to self, we may not want to remove the last character...
HEADER += '", '

#Signature Method
HEADER += 'oauth_signature_method="HMAC-SHA1", '

#Timestamp
HEADER += 'oauth_timestamp="' + TIMESTAMP + '", '

#Version
HEADER += 'oauth_version="1.0"'

print(HEADER_TITLE + "\n" + HEADER)

print(urllib.request.urlopen(urllib.request.Request(REQUEST_URL, bytes(HEADER_TITLE+HEADER, 'utf-8'))).read())

Наконец, я хотел бы отметить, что мне известно о существовании модулей Python OAuth и Twitter, которые помогают в разработке для этого. Однако, как опыт обучения, я предпочитаю не использовать их.

Заранее большое спасибо за ваше время и помощь.

Error: User Rate Limit Exceeded

Apr 10, 2012, 12:21 AMот

2ответа

0

Error: User Rate Limit Exceeded

Error: User Rate Limit ExceededError: User Rate Limit Exceeded

  1. Convert the HTTP Method to uppercase and set the output string equal to this value.
  2. Append the '&' character to the output string.
  3. Percent encode the URL and append it to the output string.
  4. Append the '&' character to the output string.
  5. Percent encode the parameter string and append it to the output string.

Error: User Rate Limit Exceeded

  1. Percent encode every key and value that will be signed.
  2. Sort the list of parameters alphabetically by encoded key.
  3. For each key/value pair:
  4. Append the encoded key to the output string.
  5. Append the '=' character to the output string.
  6. Append the encoded value to the output string.
  7. If there are more key/value pairs remaining, append a '&' character to the output string.
9

Error: User Rate Limit Exceeded

  1. I swapped out binascii.b2a_base64 for base64.standard_b64encode
  2. I converted the bytes to string using the bytes.decode('ascii') method. str() seemed to be appending b to the string.
  3. I fixed the order of the parameters to hmac.new - it's KEY, MESSAGE, not MESSAGE, KEY
  4. I removed the reference to include_entities in PARAMETER_STRING - if you don't use include_entities in the request (and I believe it doesn't make sense for the token request) it mustn't be included in the PARAMETER_STRING
  5. I added oauth_callback=oob to the begin of the PARAMETER_STRING - all oauth parameters except for the oauth_signature must be included in the base string.
  6. I changed the section where the request is made to pre-create the Request object, then add the Authorization header - you were sending the Authorization header as the HTTP body.
  7. To match this change, I removed the trailing semicolon from HEADER_TITLE.
  8. I added the missing semicolon after oauth_callback="oob".

Error: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

import urllib.parse, urllib.request, json
from hashlib import sha1
import hmac
import base64
import time
import random
import sys

#Server Links
REQUEST_URL = "https://api.twitter.com/oauth/request_token";
ACCESS_URL = "https://api.twitter.com/oauth/access_token";
AUTHORIZE_URL = "https://api.twitter.com/oauth/authorize";

#Consumer keys
TOKEN = "Omitted"
TOKEN_SECRET = "Omitted"

#Access keys
ACCESS_TOKEN = ""
ACCESS_TOKEN_SECRET = ""

TWEET = ""

count = 1

while len(sys.argv) > count:
TWEET += sys.argv[count] + " "
count += 1

TWEET = TWEET[:-1] #Get rid of trailing space

print(TWEET + "\n")

#Build content header for POST to return request tokens

HEADER_TITLE = "Authorization"

#Consumer key
HEADER = 'OAuth oauth_callback="oob", oauth_consumer_key="' + TOKEN + '", '

#Nonce
HEADER += 'oauth_nonce="'
NONCE = ""
for i in range(32):
NONCE += chr(random.randint(97, 122))
HEADER += NONCE
HEADER += '", '

#Timestamp
TIMESTAMP = str(int(time.time()))

#Signature
HEADER += 'oauth_signature="'
PARAMETER_STRING = "oauth_callback=oob&oauth_consumer_key=" + TOKEN + "&oauth_nonce=" + NONCE + "&oauth_signature_method=HMAC-SHA1&oauth_timestamp=" + TIMESTAMP + "&oauth_version=1.0"
BASE_STRING = 'POST&' + urllib.parse.quote(REQUEST_URL, '') + '&' + urllib.parse.quote(PARAMETER_STRING, '')
SIGNING_KEY = urllib.parse.quote(TOKEN_SECRET, '') + '&'
print("DEBUG : SIGNING KEY " + SIGNING_KEY + " BASE STRING " + BASE_STRING + "\n")
HEADER += urllib.parse.quote(base64.standard_b64encode(hmac.new(SIGNING_KEY.encode(), BASE_STRING.encode(), sha1).digest()).decode('ascii'))
HEADER += '", '

#Signature Method
HEADER += 'oauth_signature_method="HMAC-SHA1", '

#Timestamp
HEADER += 'oauth_timestamp="' + TIMESTAMP + '", '

#Version
HEADER += 'oauth_version="1.0"'

print(HEADER_TITLE + ":\n" + HEADER)

HTTP_REQUEST = urllib.request.Request(REQUEST_URL)
HTTP_REQUEST.add_header(HEADER_TITLE, HEADER)
print(urllib.request.urlopen(HTTP_REQUEST, bytes('', 'ascii')).read())

RelatedQuestions