2011-09-05 14 views
5

Tôi đã sử dụng thư viện để xử lý OAuth cho đến nay, nhưng gần đây tôi đã tìm hiểu sâu hơn về cách hiểu quy trình OAuth cơ bản. Hiện nay, tôi đang cố gắng để kết nối với Tumblr API v2 sử dụng OAuth 1.0a với mã đơn giản này:Không thể nhận Mã thông báo yêu cầu OAuth khi làm việc với API Tumblr bằng cách sử dụng Python

import urllib, urllib2, time, random, hmac, base64, hashlib 

def makenonce(): 
    random_number = ''.join(str(random.randint(0, 9)) for _ in range(40)) 
    m = hashlib.md5(str(time.time()) + str(random_number)) 
    return m.hexdigest() 

def encodeparams(s): 
    return urllib.quote(str(s), safe='~') 

# Actual key and secret from a test app created using a dummy Tumblr account 
consumer_key = '97oAujQhSaQNv4XDXzCjdZlOxwNyhobmDwmueJBCHWsFFsW7Ly' 
consumer_secret = '5q1dpF659SOgSUb0Eo52aAyoud8N8QOuJu6enCG92aDR6WoMlf' 

#oauth URLs 
request_tokenURL = 'http://www.tumblr.com/oauth/request_token' 

#oauth params 
oauth_parameters = { 
      'oauth_consumer_key'  : consumer_key, 
      'oauth_nonce'   : makenonce(), 
      'oauth_timestamp'  : str(int(time.time())), 
      'oauth_signature_method' : "HMAC-SHA1", 
      'oauth_version'   : "1.0" 
      } 

normalized_parameters = encodeparams('&'.join(['%s=%s' % (encodeparams(str(k)), encodeparams(str(oauth_parameters[k]))) for k in sorted(oauth_parameters)])) 
# Since I'm focusing only on getting the request token for now, I set this to POST. 
normalized_http_method = 'POST' 
normalized_http_url = encodeparams(request_tokenURL) 
signature_base_string = '&'.join([normalized_http_method, normalized_http_url, normalized_parameters]) 
oauth_key = consumer_secret + '&' 
hashed = hmac.new(oauth_key, signature_base_string, hashlib.sha1) 
oauth_parameters['oauth_signature'] = base64.b64encode(hashed.digest()) 
oauth_header = 'Authorization: OAuth realm="http://www.tumblr.com",' + 'oauth_nonce="' + oauth_parameters['oauth_nonce'] + '",' + 'oauth_timestamp="' + oauth_parameters['oauth_timestamp'] + '",' + 'oauth_consumer_key="' + oauth_parameters['oauth_consumer_key'] + '",' + 'oauth_signature_method="HMAC-SHA1",oauth_version="1.0",oauth_signature="' + oauth_parameters['oauth_signature'] +'"' 

# sample oauth_header generated by the code above: 
# Authorization: OAuth realm="http://www.tumblr.com",oauth_nonce="c200a0e06f30b84b851ac3e99a71054b",oauth_timestamp="1315231855",oauth_consumer_key="97oAujQhSaQNv4XDXzCjdZlOxwNyhobmDwmueJBCHWsFFsW7Ly",oauth_signature_method="HMAC-SHA1",oauth_version="1.0",oauth_signature="kVAlmwolCX0WJIvTF9MB2UV5rnU=" 


req = urllib2.Request(request_tokenURL) 
req.add_header('Authorization', oauth_header) 
# If all goes well, Tumblr should send me the oauth request token. 
print urllib2.urlopen(req).read() 

Thay vì OAuth Yêu cầu mã thông báo, Tumblr trả Lỗi HTTP 401: Unauthorized.

Những điều tôi đã cố gắng mà không thành công:

  1. Changed oauth_version từ "1.0" thành "1.0a", và thay đổi nó trở lại.
  2. Hướng dẫn về OAuth được ủy quyền thêm '&' vào cuối consumer_secret để nhận được oauth_key. Tôi đã thử xóa '&' sau này để xem điều đó có tạo ra bất kỳ sự khác biệt nào không.
  3. Kiểm tra xem các tham số OAuth đã được sắp xếp hay chưa.
  4. Không thêm chuỗi "Ủy quyền:" vào oauth_header, sau đó thêm lại sau. Không có bất kỳ sự khác biệt nào.

Tôi đã gặp lỗi ở đâu?

+0

Có thể bạn không nên có khóa bí mật ở đây –

+0

@Cal Đây là một ứng dụng giả được tạo riêng cho câu hỏi này. Nó nằm ngay trong các bình luận: '// Chìa khóa thực tế và bí mật từ một ứng dụng thử nghiệm được tạo ra bằng cách sử dụng một tài khoản Tumblr ** giả **. – vjk2005

Trả lời

4

Giải quyết nó sau khi thực hiện chỉ 2 thay đổi đơn giản trong đoạn code trên:

  1. normalized_http_method = 'GET' #not POST
  2. oauth_header = 'OAuth realm="http://www...' # Từ "Cho Phép" là không cần thiết. Tôi đã thực hiện điều này trước đó như được liệt kê trong "Những điều tôi đã thử mà không có bất kỳ thành công", nhưng lỗi được liệt kê trong (1) đã ném tôi đi theo dõi. Với (1) giải quyết, tôi có thể thấy cách "Ủy quyền" thực sự là không cần thiết.

Các OAuth Yêu cầu thẻ Tumblr đã gửi cho tôi khi tôi cuối cùng đã nhận nó đúng: oauth_token=mbRUgyDkPePfkEztiLELMqUl1kyNXEcaTCCwpb7SoXDF9mhiTF&oauth_token_secret=5pXllXGKA8orAaUat1G7ckIfMfYup8juMBAgEELUkeMZoC3pv6&oauth_callback_confirmed=true

Đây là một lần duy nhất token và tôi đã liệt kê nó ở đây chỉ dành riêng cho vì lợi ích của sự hoàn chỉnh.

+0

Có lẽ bạn nên xem xét điều này: https://github.com/simplegeo/python-oauth2 – DocWiki