目前我正在使用OAuth协议连接Twitter API并在Python中编写代码。作为大多数用户,我认为规范中最棘手的部分是处理签名。
在网上闲逛寻找解决方案之后,我决定选择我的自定义代码,以便更好地了解正在发生的事情。
为了其他用户,我在这里发布了一个非常简单而简短的Python中SHA1签名规范的实现:
import hmac
from hashlib import sha1
from urllib import quote, urlencode
from base64 import b64encode
from urlparse import urlparse
def sign_request_sha1(url,method,data,secret=""):
pu = urlparse(urlparse(url).geturl())
normUrl = "%s://%s%s%s" % (
pu.scheme,
pu.hostname,
"" if not pu.port or {"http":80,"https":443}[pu.scheme] == pu.port else ":%d" % pu.port,
pu.path,
)
names = data.keys()
names.sort()
sig = "%s&%s&%s" % (
method.upper(),
quote(normUrl,''),
quote("&".join(["%s=%s" % (k,quote(data[k].encode('utf-8'),'')) for k in names]),''),
)
key = "%s&%s" % (quote(CONSUMER_SECRET.encode('utf-8'),''),secret)
return b64encode(hmac.new(key,sig,sha1).digest())
该函数的输入参数是:
我用Twitter测试过它似乎有用,但我想收到一些关于错误,改进等的评论。
最后,在这里,您可以找到一段代码,用于调用初始“请求令牌”阶段的代码:
from random import getrandbits
from base64 import b64encode
from time import time
def twitter_request_token(req,callback,errback):
req_url="http://twitter.com:80/oauth/request_token"
data = { \
"oauth_consumer_key" : CONSUMER_KEY,
"oauth_nonce" : b64encode("%0x" % getrandbits(256))[:32],
"oauth_timestamp" : str(int(time())),
"oauth_signature_method" : "HMAC-SHA1",
"oauth_version" : "1.0",
"oauth_callback" : "http://localhost:8080/",
}
data["oauth_signature"] = sign_request_sha1(req_url,"GET",data)
谢谢。
答案 0 :(得分:3)
我对此的下意识反应是If You're Typing The Letters A-E-S Into Your Code, You're Doing It Wrong。或者,作为redditor khafra recently reminded us of the Sicilian's version:
哈哈,你这个笨蛋!你成了一个经典失误的牺牲品。最着名的是:永远不要卷入亚洲的陆战。但是只有一点点不那么有名:当有一个经过充分测试的库可以做得更好时,永远不要尝试自己的加密!
我的意思是,我明白了。我第一次看到它时,oauth.py也没有让我印象深刻。从那以后它已经做了很多工作并且它看起来更好,但似乎仍然没有测试,所以我不知道。无论如何,测试或没有测试,它已被更多的人审查和使用,而不是代码。
但这只是我对加密代码重用主题的紧张,并没有真正帮助你搞清楚协议机制。对我来说看起来没问题,但我最近没有太多关注OAuth规范。
为pu.port
业务使用更多行;条件if
表达式,or
表达式和{}[]
构造都在一行中真的难以阅读。
如果您真的想要熟悉该协议的人进行代码审查,那么您最好不要问the mailing list。如果你能为他们提供一个替代API,使他们的存储库中的代码对新用户更具吸引力,那对每个人都有好处。