目前我正在使用OAuth協議連接Twitter API並使用Python編寫代碼。作爲大多數用戶,我認爲規格中最難的部分是處理簽名。在Python中爲OAuth簽名請求
在圍繞網絡尋找解決方案之後,我決定去我的自定義代碼,以便更好地理解發生了什麼。
對於其他用戶着想,我在這裏張貼一個非常簡單的和短期實現SHA1簽名規格的Python中:
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())
的輸入參數的功能是:
- 網址:您要爲特定的OAuth請求調用的網址。
- 方法:根據您要發出請求的方式,這必須是「GET」或「POST」。
- data:包含所有請求參數的字典,包括任何自定義參數,但不包括「oauth_signature」(出於顯而易見的原因)。
- 祕密:您在協議初始階段收到的祕密令牌。
我用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)
謝謝。
你能解釋一下'normURL'練習的重點嗎? – SilentGhost 2010-01-26 10:14:13
規格對於用於創建簽名的URL必須是非常嚴格的。 因此,從傳遞的URL開始,可能不符合規範(例如,由於某些字符爲大寫),該函數會生成一個新的URL。 第一行利用urlparse模塊獲得URL的第一次清理:這裏我不確定是否唯一的影響是使所有字符小寫。 在字符串插值中,它使用URL元素來形成新的URL,當它是所使用的方案的缺省值(80代表http和443代表https)時,省略端口。 – 2010-01-26 13:29:56
所以你寫這個代替oauth.googlecode.com的代碼? – keturn 2010-01-27 01:19:02