【问题标题】:PUT-parameters in django-rest-framework + OAuth 1.0adjango-rest-framework + OAuth 1.0a 中的 PUT 参数
【发布时间】:2014-06-15 07:19:39
【问题描述】:

点冻结

Django==1.6.2
Markdown==2.3.1
South==0.8.4
argparse==1.2.1
django-filter==0.7
django-guardian==1.1.1
django-oauth-plus==2.2.3
django-registration==1.0
djangorestframework==2.3.11
httplib2==0.8
ipdb==0.8
ipython==2.0.0
oauth2==1.5.211
psycopg2==2.5.2
wsgiref==0.1.2

请求:

PUT /api/v1/place/14/ BODY: name=NEW3&latitude=55.74659&longitude=37.626484

回复:

{"detail": "Invalid signature. Expected signature base string: PUT&http%3A%2F%2Fyavezu.com%3A8005%2Fapi%2Fv1%2Fplace%2F14%2F&oauth_consumer_key%3Daa68ec89fc944c60880f59e18dc6e982%26oauth_nonce%3D-4587244018477714645%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1398769361%26oauth_token%3D03cd9df066244aa2884a5508ff0d9fff%26oauth_version%3D1.0"}

如您所见,基本字符串中不包含 PUT 参数。

我挖了一点代码,发现了两个原因。

  1. oauth_provider 不支持 PUT 参数

见行:

if request.method == "POST" and request.META.get('CONTENT_TYPE') == "application/x-www-form-urlencoded":

oauth_provider.utils

def get_oauth_request(request):
    """ Converts a Django request object into an `oauth2.Request` object. """
    # Django converts Authorization header in HTTP_AUTHORIZATION
    # Warning: it doesn't happen in tests but it's useful, do not remove!
    auth_header = {}
    if 'Authorization' in request.META:
        auth_header = {'Authorization': request.META['Authorization']}
    elif 'HTTP_AUTHORIZATION' in request.META:
        auth_header =  {'Authorization': request.META['HTTP_AUTHORIZATION']}


    # include POST parameters if content type is
    # 'application/x-www-form-urlencoded' and request
    # see: http://tools.ietf.org/html/rfc5849#section-3.4.1.3.1
    parameters = {}

    if request.method == "POST" and request.META.get('CONTENT_TYPE') == "application/x-www-form-urlencoded":
        parameters = dict((k, v.encode('utf-8')) for (k, v) in request.POST.iteritems())

    absolute_uri = request.build_absolute_uri(request.path)

    if "HTTP_X_FORWARDED_PROTO" in request.META:
        scheme = request.META["HTTP_X_FORWARDED_PROTO"]
        absolute_uri = urlunparse((scheme, ) + urlparse(absolute_uri)[1:])

    return oauth.Request.from_request(request.method,
        absolute_uri,
        headers=auth_header,
        parameters=parameters,
        query_string=request.META.get('QUERY_STRING', '')
    )
  1. django.core.handlers.wsgi.WSGIRequestdjango.http.request.HttpRequest 类不支持 PUT 参数:

    def _load_post_and_files(self): """如果内容类型是表单类型,则填充 self._post 和 self._files""" 如果 self.method != 'POST': self._post, self._files = QueryDict('', encoding=self._encoding), MultiValueDict() 返回 ...

我想知道 Django REST 框架如何在不支持 PUT 参数的情况下通过 Django 提供 RESTful API?我究竟做错了什么? POST 请求工作得很好。

我也在 Google 网上论坛上问过这个问题: https://groups.google.com/forum/m/?fromgroups#!topic/django-rest-framework/679fOg0QpzI

【问题讨论】:

  • 看起来这个对 django-oauth-plus 的修复应该会有所帮助: if request.META.get('CONTENT_TYPE', None) == "application/x-www-form-urlencoded": if request.method == 'POST': 参数 = request.POST else: 参数 = getattr(request, 'DATA', {}) 参数 = dict((k, v.encode('utf-8')) for (k , v) 在 parameters.iteritems()) 中

标签: python django rest oauth django-rest-framework


【解决方案1】:

根据google groups thread上的回答...

我建议:

  1. 而是将身份验证信息放在 Authorization 标头中,django-oauth-plus 也正确支持。
  2. 向 django-oauth-plus 提交拉取请求,添加对在非 POST 消息正文中包含 x-www-form-urlencoded oauth 参数的支持。

无论哪种方式,问题都不在于 REST 框架不支持解析 PUT 请求中的数据 - 它支持,并且 request.DATA 仍将正常填充。

【讨论】:

    猜你喜欢
    • 2014-05-19
    • 1970-01-01
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    • 2020-07-08
    • 1970-01-01
    • 1970-01-01
    • 2013-03-30
    相关资源
    最近更新 更多