Python中带有Twitter脚本的OAuth不起作用

Python中带有Twitter脚本的OAuth不起作用,python,oauth,twitter,Python,Oauth,Twitter,我正在用Python编写OAuth脚本 为了测试这一点,我使用了twitterapi。但它并不奏效 def test(): params = { "oauth_consumer_key": TWITTER_OAUTH_CONSUMER_KEY, "oauth_nonce": "".join(random.choice(string.digits + string.letters) for i in xrange(7)),

我正在用Python编写OAuth脚本

为了测试这一点,我使用了twitterapi。但它并不奏效

def test():
    params = {
            "oauth_consumer_key": TWITTER_OAUTH_CONSUMER_KEY,
            "oauth_nonce": "".join(random.choice(string.digits + string.letters) for i in xrange(7)),
            "oauth_signature_method": "HMAC-SHA1",
            "oauth_timestamp": str(int(time.time())),
            "oauth_token": res_dict["oauth_token"],
            "oauth_version": "1.0",
            }
    status = {"status": u"Always_look_on_the_bright_side_of_life".encode("UTF-8")}
    print status
    params.update(status)
    url = "http://twitter.com/statuses/update.xml"
    key = "&".join([TWITTER_OAUTH_CONSUMER_SECRET, res_dict["oauth_token_secret"]])
    msg = "&".join(["POST", urllib.quote(url,""),
                    urllib.quote("&".join([k+"="+params[k] for k in sorted(params)]), "-._~")])
    print msg
    signature = hmac.new(key, msg, hashlib.sha1).digest().encode("base64").strip()
    params["oauth_signature"] = signature
    req = urllib2.Request(url,
          headers={"Authorization":"OAuth", "Content-type":"application/x-www-form-urlencoded"})
    req.add_data("&".join([k+"="+urllib.quote(params[k], "-._~") for k in params]))
    print req.get_data()
    res = urllib2.urlopen(req).read()
    print res
这个脚本(status=“始终关注生活的光明面”)正在运行

但是,如果状态为“始终看到生活的光明面”(下划线替换为空格),则它不起作用(返回HTTP错误401:Unauthorized)

我引用了,但失败了


请给我一些建议。谢谢。

解决这个问题的最简单方法是在
status={“status”:u“总是关注生活光明的一面”。encode(“UTF-8”)}
之后添加
status=urllib.quote(status)
。这将根据需要转义空格和其他特殊字符。

我不久前在OAuth和FaceBook中遇到了同样的问题。问题是服务器端的签名验证失败。请参见此处的签名生成代码:

msg = "&".join(["POST", urllib.quote(url,""),
                urllib.quote("&".join([k+"="+params[k] for k in sorted(params)]), "-._~")])
print msg
signature = hmac.new(key, msg, hashlib.sha1).digest().encode("base64").strip()
它使用字符串的原始(非编码)形式来生成签名。但是,服务器端根据URL引用字符串生成并验证签名:

req.add_data("&".join([k+"="+urllib.quote(params[k], "-._~") for k in params]))
要修复代码,您需要通过从url编码参数创建签名来修复此行:

msg = "&".join(["POST", urllib.quote(url,""),
                urllib.quote("&".join([k+"="+urllib.quote(params[k], "-._~") for k in sorted(params)]), "-._~")])

+1用于在Python示例中使用适当的示例字符串。