在 Python 中为 OAuth 签署请求 [英] Signing requests in Python for OAuth

查看:64
本文介绍了在 Python 中为 OAuth 签署请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我正在使用 OAuth 协议连接 Twitter API 并用 Python 编写代码.作为大多数用户,我认为规范中最困难的部分是处理签名.

currently I'm interfacing the Twitter API using the OAuth protocol and writing the code in Python. As most of the users out there, I think the toughest part of the specs is dealing with signatures.

在网上四处寻找解决方案后,我决定使用我的自定义代码,以便更好地了解正在发生的事情.

After wandering around the web in search for a solution, I decided to go for my custom code, so as to have a better understanding of what is going on.

为了其他用户,我在这里发布了一个非常简单且简短的 Python SHA1 签名规范实现:

For the sake of other users, I'm posting here a very simple and short implementation of the SHA1 signature specs in 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())

函数的输入参数为:

  • url:您要为特定 OAuth 请求调用的 url.
  • 方法:这必须是GET"或POST",具体取决于您将如何发出请求.
  • data:包含请求的所有参数的字典,包括任何自定义参数,但不包括oauth_signature"参数(出于显而易见的原因).
  • 秘密:您在协议初始阶段收到的秘密令牌.

我在 Twitter 上对其进行了测试,它似乎有效,但我希望收到一些关于错误、改进等方面的评论.

I tested it with Twitter and it seems to work but I'd like to receive some comments about mistakes, improvements and so on.

最后,这里有一段代码调用初始请求令牌"阶段的代码:

Lastly, here you find a piece of code calling the code for the initial "request token" phase:

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)

谢谢.

推荐答案

我下意识的反应是 如果您在代码中输入 AES 字母,那您就做错了.或者,正如 redditor khafra 最近让我们想起了西西里的版本:

My knee-jerk reaction to this is If You're Typing The Letters A-E-S Into Your Code, You're Doing It Wrong. Or, as redditor khafra recently reminded us of the Sicilian's version:

哈哈..你这个笨蛋!你成为了一个经典错误的受害者.最著名的是:永远不要卷入亚洲的陆战.但唯一不那么出名的是:当有一个经过良好测试的库可以做得更好时,永远不要尝试推出自己的加密!

Haha.. you fool! You fell victim to one of the classic blunders. The most famous is: Never get involved in a land war in Asia. But only slightly less famous is this: Never attempt to roll your own crypto when there's a well-tested library that'll do it better!

我的意思是,我明白了.我第一次看它时,oauth.py也不给我留下深刻印象.从那以后已经做了很多工作,看起来好多了,但似乎仍然没有测试,所以我不知道.不管怎样,不管是测试还是不测试,它被审查和使用的人比你的代码还多.

I mean, I get it. The first time I looked at it, oauth.py didn't impress me either. There's been a lot of work on it since and it's looking better, but there still appear to be no tests, so I don't know. Anyway, tests or no tests, it's been reviewed and used by more people than your code has.

但这只是我对加密代码重用的主题持谨慎态度,并不能真正帮助您弄清楚协议机制.对我来说看起来还可以,但我最近对 ​​OAuth 规范不太了解.

But that's just me being uptight on the subject of crypto code reuse and doesn't really help you in figuring out the protocol machinery. It looks okay to me, but I haven't had my head in the OAuth spec too much lately.

只需为 pu.port 业务使用更多行;在一行中包含条件 if 表达式、or 表达式和 {}[] 构造真的 难以阅读.

Just use some more lines for that pu.port business; having a conditional if expression, an or expression, and the {}[] construct all in one line is really hard to read.

如果您真的希望熟悉协议的人进行代码审查,那么您最好询问 邮件列表.如果您可以为他们提供替代 API,让他们的代码库中的代码对新用户更具吸引力,那对每个人都会有好处.

If you really want code review by people who are familiar with the protocol, you're probably better off asking the mailing list. And if you can offer them an alternate API that will make the code in their repository more appealing to new users, that'll be good for everyone.

这篇关于在 Python 中为 OAuth 签署请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆