使用 Python 3 从 Twitter API 检索请求令牌

2024-05-05

我正在尝试使用 Python 3 与 Twitter API 交互,以返回页面的链接,该页面为我提供了用于请求访问令牌的 PIN 码。详细信息如下:https://dev.twitter.com/docs/auth/pin-based-authorization https://dev.twitter.com/docs/auth/pin-based-authorization

Twitter 的 API 回复我,告诉我我没有通过返回 401 正确授权我的 POST 请求。我对原因的最佳猜测是我没有正确地以 base64 编码 HMAC 签名。根据我查看过的正确 POST 请求的示例,我生成的 POST 请求的所有其他部分看起来都是正确的。

我花了几天的时间来解决这个问题,我希望有人能帮助我完成最后一部分。

以下是 Twitter API 文档中最相关的部分:https://dev.twitter.com/docs/api/1/post/oauth/request_token https://dev.twitter.com/docs/api/1/post/oauth/request_token

https://dev.twitter.com/docs/auth/authorizing-request 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 模块的存在有助于这方面的开发。然而,作为一种学习经历,我选择不使用它们。

预先非常感谢您的时间和帮助。


我所做更改的概述:

  1. 我换了binascii.b2a_base64 for base64.standard_b64encode
  2. 我使用以下命令将字节转换为字符串bytes.decode('ascii')方法。 str() 似乎将 b 附加到字符串中。
  3. 我将参数的顺序固定为hmac.new - it's KEY, MESSAGE, not MESSAGE, KEY
  4. 我删除了对include_entities in PARAMETER_STRING- 如果您不在请求中使用 include_entities (并且我相信这对于令牌请求没有意义),则不得将其包含在 PARAMETER_STRING 中
  5. I added oauth_callback=oob到开始PARAMETER_STRING- 除 oauth_signature 之外的所有 oauth 参数都必须包含在基本字符串中。
  6. 我更改了发出请求的部分以预先创建 Request 对象,然后添加 Authorization 标头 - 您将 Authorization 标头作为 HTTP 正文发送。
  7. 为了匹配此更改,我删除了尾随分号HEADER_TITLE.
  8. 我在之后添加了缺少的分号oauth_callback="oob".

Enjoy!

这是代码的固定版本:

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())
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Python 3 从 Twitter API 检索请求令牌 的相关文章

随机推荐

  • AutoCompleteTextView 不显示建议

    我正在尝试为 android 创建一个应用程序 我想在其中保留AutoCompleteTextView显示减少用户工作量的建议 目前我正在使用我编写的小代码进行测试 但没有得到建议 我把代码贴出来 请帮我找出错误 public class
  • *_在 Django 模型上设置属性

    我有一个非常基本的问题django db models In this 官方 Django 教程 https docs djangoproject com en 1 4 intro tutorial01 如果您搜索单词 choice set
  • “wget -O”是什么意思?

    我的 shell 脚本中有一个像这样的 wget 命令 reponse wget O http localhost 8080 app index html 我不明白 O 选项 有人向我解释说 O 输出到某个地方 输出到当前流 我在 wget
  • 在 R 中使用 glmnet 和 dotCall64 的长向量

    我使用 glmnet 和 glmnetcr 来拟合序数回归模型 不幸的是 我的模型矩阵约为 640000 5000 这大于可以存储在 32 位整数中的大小 并且我遇到了其他人描述的相同问题 R 向量大小限制 C 中不支持长向量 参数 5 h
  • 正则表达式匹配没有给定前缀的特定字符串

    我需要匹配包含值且没有给定前缀的所有行 例子 我想要包含的所有行word当它没有前缀时prefix So foobar gt no match prefix word gt no match prefix word suffix gt no
  • 查看作为 TFS 中工作项的一部分更改的所有文件的列表

    如果我针对工作项签入代码 则每次签入都会创建一个变更集 我可以查看工作项的链接选项卡 然后查看每个变更集以查看已更改的文件 然而 随着时间的推移 工作项可能最终会产生许多变更集 并且查找所有已更改的文件可能是一个非常耗时且痛苦的过程 有没有
  • 在多个 Compass 项目中加载全局 SASS 文件

    我想创建一个多个 Compass 项目将访问的 SASS 文件目录 该目录将包含许多具有相似样式 表单元素 clearfixes 重置等 的常见元素的 SASS 文件 我希望在多个项目中访问和使用这些元素 如何在多个项目中包含这个全局 SA
  • Kivy pygame错误

    我一直在尝试让 Kivy 在我的 Mac Lion 上运行 但遇到了问题 我按照 Kivy 网站上的说明进行操作 由于 Kivy 1 8 支持 Python 3 所以我想使用 3 3 运行它 最后通过编辑 kivy 文件以指向 3 3 而不
  • 如何使用 Android Studio 2.1.3 从 Android 中的文本文件中获取随机行?

    我有一个 500 行的文本文件 我将此文本文件放置在 app src main assets 文件夹中 名称为 words txt 在此文件中 每一行都用换行符分隔 现在我需要从这个文本文件中获取随机行 在发布此内容之前 我访问了以下问题
  • 如何在 webgl 中缩放纹理?

    我有一个尺寸为 800x600 的纹理 如何在 webgl 上缩放它
  • 使用正则表达式惰性(不贪婪)匹配多个组

    我想获取成对之间任何值的内容
  • 错误:获取远程存储库“origin”时出错,返回状态代码-1:

    我在 Windows 上运行 Jenkins 当我尝试通过 jenkins 构建我的项目时 出现以下错误 git exe c core askpass true fetch tags progress
  • 在Oracle中,是否可以将以逗号分隔的非常大的字符串(clob)转换为具有更好性能的表

    我需要通过逗号分隔符将非常大的 clob 字符串转换为表 下面的函数需要很长时间 有没有返回表的快速函数 create or replace FUNCTION UDF STRSPLIT2 P STR IN CLOB P DELIM IN V
  • 如何在点击时从 webview 获取 URL

    我怎样才能获得 点击的URL webview在其点击事件上 Override public void onClick View v if v getId R id webview Here i want to get clicked url
  • n 二叉树的后序遍历

    我需要以下代码的帮助来回答 我正在尝试使用堆栈而不是递归在 n 叉树上执行后序遍历 因为 python 有 1000 次递归的限制 我找到了相同的预序遍历代码 https www geeksforgeeks org iterative pr
  • Ubuntu 16.04 中 kubeadm join 命令每次都会超时

    我正在使用 Ubuntu 16 04 Xenial 但我遇到了一个问题kubeadm加入时nodes to my master 在加入一个node to my master 我不断遇到超时问题 discovery Failed to req
  • 动态添加变量名称值对到 JSON 对象

    我有一个充满 ips 的 json 对象 例如 var ips 然后我将 ip 对象添加到该对象 如下所示 ips ipID 然后我需要向每个 ip 添加动态 变量名称值对 所以我使用这样的代码 var name var value var
  • 下标的使用不明确

    该代码块以前可以工作 但现在不行了 我在纬度和经度变量上收到错误 下标 的使用不明确 这是怎么回事 这是因为 Swift 更新吗 func showPrecincts var urlBoundaries http www oklahomad
  • 从 Storm Bolt 将行插入 HBase

    我希望能够从分布式 非本地 Storm 拓扑将新条目写入 HBase 有一些 GitHub 项目提供以下任一功能 HBase 映射器 https github com ptgoetz storm hbase or 预制风暴螺栓 https
  • 使用 Python 3 从 Twitter API 检索请求令牌

    我正在尝试使用 Python 3 与 Twitter API 交互 以返回页面的链接 该页面为我提供了用于请求访问令牌的 PIN 码 详细信息如下 https dev twitter com docs auth pin based auth