通过 Django Piston 请求令牌抛出 TypeError 异常
当尝试在 Django Piston 中通过 OAuth 进行身份验证时,会引发以下异常:
Environment:
Request Method: GET
Request URL: http://localhost:8000/api/oauth/request_token/?oauth_nonce=32921052&oauth_timestamp=1291331173&oauth_consumer_key=ghof7av2vu8hal2hek&oauth_signature_method=HMAC-SHA1&oauth_version=1.0&oauth_signature=
Python Version:
Traceback:
File "/Users/derek/.virtualenvs/optimal-rest/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
100. response = callback(request, *callback_args, **callback_kwargs)
File "/Users/derek/.virtualenvs/optimal-rest/lib/python2.7/site-packages/piston/authentication.py" in oauth_request_token
130. token = oauth_server.fetch_request_token(oauth_request)
File "/Users/derek/.virtualenvs/optimal-rest/lib/python2.7/site-packages/piston/oauth.py" in fetch_request_token
302. self._check_signature(oauth_request, consumer, None)
File "/Users/derek/.virtualenvs/optimal-rest/lib/python2.7/site-packages/piston/oauth.py" in _check_signature
393. valid_sig = signature_method.check_signature(oauth_request, consumer, token, signature)
File "/Users/derek/.virtualenvs/optimal-rest/lib/python2.7/site-packages/piston/oauth.py" in check_signature
482. built = self.build_signature(oauth_request, consumer, token)
File "/Users/derek/.virtualenvs/optimal-rest/lib/python2.7/site-packages/piston/oauth.py" in build_signature
513. hashed = hmac.new(key, raw, sha)
File "/usr/local/Cellar/python/2.7/lib/python2.7/hmac.py" in new
133. return HMAC(key, msg, digestmod)
File "/usr/local/Cellar/python/2.7/lib/python2.7/hmac.py" in __init__
72. self.outer.update(key.translate(trans_5C))
Exception Type: TypeError at /api/oauth/request_token/?oauth_nonce=32921052&oauth_timestamp=1291331173&oauth_consumer_key=ghof7av2vu8hal2hek&oauth_signature_method=HMAC-SHA1&oauth_version=1.0&oauth_signature=
Exception Value: character mapping must return integer, None or unicode
无法判断这是 Piston 中的错误还是我无法使用 oauth2 lib。
消费者代码:
import os
import cgi
import oauth2 as oauth
# settings for the local test consumer
CONSUMER_SERVER = os.environ.get("CONSUMER_SERVER") or 'localhost'
CONSUMER_PORT = os.environ.get("CONSUMER_PORT") or '8000'
print CONSUMER_SERVER , CONSUMER_PORT
# fake urls for the test server (matches ones in server.py)
REQUEST_TOKEN_URL = 'http://%s:%s/api/oauth/request_token/' % (CONSUMER_SERVER, CONSUMER_PORT)
ACCESS_TOKEN_URL = 'http://%s:%s/api/oauth/access_token/' % (CONSUMER_SERVER, CONSUMER_PORT)
AUTHORIZE_URL = 'http://%s:%s/api/oauth/authorize/' % (CONSUMER_SERVER, CONSUMER_PORT)
# key and secret granted by the service provider for this consumer application - same as the MockOAuthDataStore
CONSUMER_KEY = 'ghof7av2vu8hal2hek'
CONSUMER_SECRET = 'ohhey'
consumer = oauth.Consumer(CONSUMER_KEY, CONSUMER_SECRET)
client = oauth.Client(consumer)
# Step 1: Get a request token. This is a temporary token that is used for
# having the user authorize an access token and to sign the request to obtain
# said access token.
resp, content = client.request(REQUEST_TOKEN_URL, "GET")
if resp['status'] != '200':
raise Exception("Invalid response %s." % resp['status'])
引用 https://github.com/clemesha/django-piston-oauth-example 为消费者代码。
When trying to authenticate via OAuth in Django Piston, the following exception is thrown:
Environment:
Request Method: GET
Request URL: http://localhost:8000/api/oauth/request_token/?oauth_nonce=32921052&oauth_timestamp=1291331173&oauth_consumer_key=ghof7av2vu8hal2hek&oauth_signature_method=HMAC-SHA1&oauth_version=1.0&oauth_signature=
Python Version:
Traceback:
File "/Users/derek/.virtualenvs/optimal-rest/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
100. response = callback(request, *callback_args, **callback_kwargs)
File "/Users/derek/.virtualenvs/optimal-rest/lib/python2.7/site-packages/piston/authentication.py" in oauth_request_token
130. token = oauth_server.fetch_request_token(oauth_request)
File "/Users/derek/.virtualenvs/optimal-rest/lib/python2.7/site-packages/piston/oauth.py" in fetch_request_token
302. self._check_signature(oauth_request, consumer, None)
File "/Users/derek/.virtualenvs/optimal-rest/lib/python2.7/site-packages/piston/oauth.py" in _check_signature
393. valid_sig = signature_method.check_signature(oauth_request, consumer, token, signature)
File "/Users/derek/.virtualenvs/optimal-rest/lib/python2.7/site-packages/piston/oauth.py" in check_signature
482. built = self.build_signature(oauth_request, consumer, token)
File "/Users/derek/.virtualenvs/optimal-rest/lib/python2.7/site-packages/piston/oauth.py" in build_signature
513. hashed = hmac.new(key, raw, sha)
File "/usr/local/Cellar/python/2.7/lib/python2.7/hmac.py" in new
133. return HMAC(key, msg, digestmod)
File "/usr/local/Cellar/python/2.7/lib/python2.7/hmac.py" in __init__
72. self.outer.update(key.translate(trans_5C))
Exception Type: TypeError at /api/oauth/request_token/?oauth_nonce=32921052&oauth_timestamp=1291331173&oauth_consumer_key=ghof7av2vu8hal2hek&oauth_signature_method=HMAC-SHA1&oauth_version=1.0&oauth_signature=
Exception Value: character mapping must return integer, None or unicode
Can't tell if it's a bug in Piston or if I can't use the oauth2 lib.
Consumer Code:
import os
import cgi
import oauth2 as oauth
# settings for the local test consumer
CONSUMER_SERVER = os.environ.get("CONSUMER_SERVER") or 'localhost'
CONSUMER_PORT = os.environ.get("CONSUMER_PORT") or '8000'
print CONSUMER_SERVER , CONSUMER_PORT
# fake urls for the test server (matches ones in server.py)
REQUEST_TOKEN_URL = 'http://%s:%s/api/oauth/request_token/' % (CONSUMER_SERVER, CONSUMER_PORT)
ACCESS_TOKEN_URL = 'http://%s:%s/api/oauth/access_token/' % (CONSUMER_SERVER, CONSUMER_PORT)
AUTHORIZE_URL = 'http://%s:%s/api/oauth/authorize/' % (CONSUMER_SERVER, CONSUMER_PORT)
# key and secret granted by the service provider for this consumer application - same as the MockOAuthDataStore
CONSUMER_KEY = 'ghof7av2vu8hal2hek'
CONSUMER_SECRET = 'ohhey'
consumer = oauth.Consumer(CONSUMER_KEY, CONSUMER_SECRET)
client = oauth.Client(consumer)
# Step 1: Get a request token. This is a temporary token that is used for
# having the user authorize an access token and to sign the request to obtain
# said access token.
resp, content = client.request(REQUEST_TOKEN_URL, "GET")
if resp['status'] != '200':
raise Exception("Invalid response %s." % resp['status'])
Referencing https://github.com/clemesha/django-piston-oauth-example for the consumer code.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是一个活塞问题,源于消费者密钥/秘密的编码问题。
解决方案是强制将从数据库返回的密钥/秘密编码为 ASCII。
在 Piston 的
store.py
文件中,修改lookup_consumer
使其看起来像这样:这里是我的 django-piston 分支,解决了这个问题。
This is a piston problem that comes from an encoding problem of the key/secret of the consumer.
The solution is to force the encoding of the key/secret returned from the database to ASCII.
In the
store.py
file of Piston, modify thelookup_consumer
so it look like this:Here is my fork of django-piston fixing this problem.
如果传入 unicode 键值,这个问题也会出现在 Piston 的“oauth.py”模块的“build_signature()”方法中。我在使用上面提到的 clemesha/django-piston-oauth-example 客户端代码时发现了这个问题,因为它保留了提示输入“PIN 码”后失败。
根本问题在此处记录为问题 #169:
https://bitbucket.org/jespern /django-piston/issue/169/oauth-request-token-error-with-hmac
上面描述的重新编码解决方案也适用于这种情况:
This problem also occurs inside Piston's "oauth.py" module's "build_signature()" method if a unicode key value is passed in. I discovered this issue while using the clemesha/django-piston-oauth-example client code mentioned above because it kept failing after the prompt for the "PIN Code".
The underlying problem is documented as issue #169 here:
https://bitbucket.org/jespern/django-piston/issue/169/oauth-request-token-error-with-hmac
The re-encoding solution described above is also applicable in this case: