OAuth请求400错误请求

时间:2017-03-17 18:17:14

标签: python django oauth python-requests urllib2

我们的应用使用来自第三方的资源。我们请求的资源应该在iframe中呈现。它的工作方式基于第三方规范:

第三方应用不提供访问令牌网址,唯一需要的网址是资源网址。话虽如此,

我们在创建OAuth对象和签名后发送帖子请求,如下所示:

import random
import time
from urlparse import parse_qsl, urlparse
from urllib import quote, urlencode
import urllib2
import binascii
import hashlib
import hmac
import webbrowser
import json
import copy
import requests

from django.http import JsonResponse
from myapp.users.models import User

CONSUMER_KEY = 'CONSUMER_KEY'
CONSUMER_SECRET = 'CONSUMER_SECRET'

q = lambda x: quote(x, safe="~")
get_timestamp = lambda: int(time.time())
get_nonce = lambda: str(str(random.getrandbits(64)) + str(get_timestamp()))

def get_sign(params, url, http_method, oauth_token_secret=""):
    """returns HMAC-SHA1 sign"""
    params.sort()
    normalized_params = urlencode(params)
    base_string = "&".join((http_method, q(url), q(normalized_params)))
    sig = hmac.new("&".join([CONSUMER_SECRET, oauth_token_secret]), base_string, hashlib.sha1)
    return binascii.b2a_base64(sig.digest())[:-1]

resource_url = 'https://example.com/cat_id/rsc_id'
resource_id = 1001
user = User.objects.get(id=216) # get a user who should have access to the resource

user_resource_data = [
    ('oauth_consumer_key', CONSUMER_KEY),
    ('oauth_nonce', get_nonce()),
    ('oauth_signature_method', "HMAC-SHA1"),
    ('oauth_timestamp', get_timestamp()),
    ('oauth_callback', 'about:blank'),
    ('oauth_version', '1.0'),
    ('resource_link_id', '%s_%s' % (resource_id, user.id)),
    ('user_id', user.id),
    ('lis_person_name_full', user.username),
    ('lis_person_name_family', user.last_name),
    ('lis_person_name_given', user.first_name),
    ('lis_person_contact_email_primary', user.email),
    # these parameters are specific to the LTI Requirements
    ('lti_message_type', 'basic-lti-launch-request'),
    ('lti_version', 'LTI-1p0')
]

signature = get_sign(user_resource_data, resource_url, "POST")
user_resource_data.append(('oauth_signature', signature))

url = "?".join((resource_url, urlencode(user_resource_data)))
resp = requests.post(resource_url, params=user_resource_data)

我也尝试使用urllib2.urlopen方法,而不是使用Python请求:

resp = urllib2.urlopen(urllib2.Request(url, data=[]))

我一直收到一个错误的请求,我不确定会出现什么问题,因为没有返回错误消息。

更新 我甚至试图创建OAuth签名并将所有参数值传递给一个角度指令,该指令填充表单的隐藏输入字段并提交它并应该在iframe中呈现返回的资源。

<div class="video-container">
   <iframe ng-hide='!loaded'
           allowfullscreen
           frameBorder="0" 
           name="launchFrame"
           id="lesson-frame"
           src="{{ source_url }}"
           scrolling="auto" 
           width="100px";>
    </iframe>
    <div>
      <form method="post" id="launch-form" action="{{ source_url }}" enctype="application/x-www-form-urlencoded">
        <input type="text" name="oauth_consumer_key" value="{{ form_data.oauth_consumer_key }}" hidden>
        <input type="text" name="oauth_signature" value="{{ form_data.oauth_signature }}" hidden>
        <input type="text" name="oauth_callback" value="auto:blank" hidden>
        <input type="text" name="oauth_signature_method" value="{{ form_data.oauth_signature_method }}" hidden>
        <input type="text" name="oauth_nonce" value="{{ form_data.oauth_nonce }}" hidden>
        <input type="text" name="user_id" value="{{ form_data.user_id }}" hidden>
        <input type="text" name="resource_link_id" value="{{ form_data.resource_link_id }}" hidden>
        <input type="text" name="lis_person_contact_email_primary" value="{{ form_data.lis_person_contact_email_primary }}" hidden>
        <input type="text" name="lis_person_name_family" value="{{ form_data.lis_person_name_family }}" hidden>
        <input type="text" name="lis_person_name_full" value="{{ form_data.lis_person_name_full }}" hidden>
        <input type="text" name="lis_person_name_given" value="{{ form_data.lis_person_name_given }}" hidden> 
        <input type="text" name="lti_message_type" value="{{ form_data.lti_message_type }}" hidden> 
        <input type="text" name="lti_version" value="{{ form_data.lti_version }}" hidden> 
        <input type="text" name="oauth_version" value="{{ form_data.oauth_version }}" hidden> 
        <input type="text" name="oauth_timestamp" value="{{ form_data.oauth_timestamp }}" hidden>
      </form>
    </div>
  </div>

source_url具有资源的url。所有其他数据都通过计算OAuth签名的django视图中的JsonResponse传递。 如果提交表单,我收到的错误是OAuth签名无效。

0 个答案:

没有答案