2010-12-02 27 views
2

當試圖通過OAuth在Django活塞進行身份驗證,以下異常被拋出:通過Django的活塞請求的令牌引發TypeError異常

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 

不能,如果它在活塞上的錯誤或告知,如果我不能使用oauth2庫。

消費者代碼:

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爲消費者代碼。

+0

我遇到了同樣的問題,你找到了解決方案嗎? – nbarraille 2011-04-08 13:05:27

回答

3

這是一個活塞問題,它來自消費者關鍵/祕密的編碼問題。 解決方法是強制將從數據庫返回的密鑰/密碼編碼爲ASCII。

store.py文件活塞,修改lookup_consumer所以它看起來像這樣:

def lookup_consumer(self, key): 
    try: 
     self.consumer = Consumer.objects.get(key=key) 
     self.consumer.key = self.consumer.key.encode('ascii') 
     self.consumer.secret = self.consumer.secret.encode('ascii') 
     return self.consumer 
    except Consumer.DoesNotExist: 
     return None 

Here是我的Django活塞修正此問題的叉。

+0

很好找。謝謝! – 2011-04-12 05:11:18

1

如果傳入unicode鍵值,活塞的「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

上述再編碼解決方案也適用於這種情況:

def build_signature(self, oauth_request, consumer, token): 
    """Builds the base signature string.""" 
    key, raw = self.build_signature_base_string(oauth_request, consumer, 
     token) 

    #BUG: character mapping must return integer, None or unicode 
    #FIX: 
    key = key.encode('ascii') 

    # HMAC object. 
    try: 
     import hashlib # 2.5 
     hashed = hmac.new(key, raw, hashlib.sha1) 
    except: 
     import sha # Deprecated 
     hashed = hmac.new(key, raw, sha) 

    # Calculate the digest base 64. 
    return binascii.b2a_base64(hashed.digest())[:-1] 
相關問題