OAuth with Twitter script in Python not working

I am writing an OAuth script in Python.

To test this, I use the Twitter API. But it does not work well.

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 

This script (status = "Always_look_on_the_bright_side_of_life") works.

But in case the status β€œAlways look at the bright side of life” (replace the underscore with a space), it does not work (returns HTTP Error 401: Unauthorized).

I referred to this question , but could not.

Please give me some advice. Thanks.

+4
source share
2 answers

I have the same problem in OAuth with FaceBook some time ago. The problem is that the server side signature verification failed. See the code for generating your signature:

 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() 

It uses the raw (non-encoded) form of the string to generate the signature. However, the server side generates a signature confirmation on the line specified in the URL:

 req.add_data("&".join([k+"="+urllib.quote(params[k], "-._~") for k in params])) 

To fix the code, you need to fix this line by creating a signature from the parameter encoded by URL:

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

The easiest way to fix this is to add status = urllib.quote(status) after status = {"status": u"Always_look_on_the_bright_side_of_life".encode("UTF-8")} . This avoids spaces and other special characters as needed.

0
source

Source: https://habr.com/ru/post/1300992/


All Articles