Vik*_*ica 4 python django curl tastypie
我正在尝试将一个ApiKey认证的POST请求发送到tastypie API
class Thing(models.Model):
name = models.TextField()
def __unicode__(self):
return u'%s'%self.name
Run Code Online (Sandbox Code Playgroud)
class ThingResource(ModelResource):
class Meta:
queryset = Thing.objects.all()
resource_name="thing"
authentication = ApiKeyAuthentication()
authorization = DjangoAuthorization()
Run Code Online (Sandbox Code Playgroud)
from django.conf.urls.defaults import patterns, include, url
from tastypie.api import Api
from myapp.api import ThingResource
mobile_api = Api(api_name='mobile')
mobile_api.register(ThingResource())
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
url(r'^admin/', include(admin.site.urls)),
(r'^api/', include(mobile_api.urls)),
)
Run Code Online (Sandbox Code Playgroud)
curl --dump-header - -H "Accept: application/json" -H "Content-Type: application/json" -d"username=vikingosegundo" -d"api_key=12345" -X POST --data "{\"name\":\"arrrg\"}" http://localhost:8000/api/mobile/thing/
Run Code Online (Sandbox Code Playgroud)
{"error_message": "No JSON object could be decoded",
"traceback": "Traceback (most recent call last):\n\n
File \"/Users/vikingosegundo/Coding/Project/serverside/mysite/tastypie/resources.py\", line 178, in wrapper\n response = callback(request, *args, **kwargs)\n\n
File \"/Users/vikingosegundo/Coding/Project/serverside/mysite/tastypie/resources.py\", line 379, in dispatch_list\n return self.dispatch('list', request, **kwargs)\n\n
File \"/Users/vikingosegundo/Coding/Project/serverside/mysite/tastypie/resources.py\", line 409, in dispatch\n response = method(request, **kwargs)\n\n
File \"/Users/vikingosegundo/Coding/Project/serverside/mysite/tastypie/resources.py\", line 1077, in post_list\n deserialized = self.deserialize(request, request.raw_post_data, format=request.META.get('CONTENT_TYPE', 'application/json'))\n\n
File \"/Users/vikingosegundo/Coding/Project/serverside/mysite/tastypie/resources.py\", line 328, in deserialize\n deserialized = self._meta.serializer.deserialize(data, format=request.META.get('CONTENT_TYPE', 'application/json'))\n\n
File \"/Users/vikingosegundo/Coding/Project/serverside/mysite/tastypie/serializers.py\", line 161, in deserialize\n deserialized = getattr(self, \"from_%s\" % desired_format)(content)\n\n
File \"/Users/vikingosegundo/Coding/Project/serverside/mysite/tastypie/serializers.py\", line 305, in from_json\n return simplejson.loads(content)\n\n
File \"/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/json/__init__.py\", line 307, in loads\n return _default_decoder.decode(s)\n\n
File \"/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/json/decoder.py\", line 319, in decode\n obj, end = self.raw_decode(s, idx=_w(s, 0).end())\n\n
File \"/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/json/decoder.py\", line 338, in raw_decode\n raise ValueError(\"No JSON object could be decoded\")\n\n
ValueError: No JSON object could be decoded\n"
}
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?如何将tastypie指向json对象?auth + auth似乎正在运行.
小智 9
使用-d和--data使用curl会破坏POSTed数据.
在GET中包含username和api_keyparams应该解决这个问题,如下所示:
curl --dump-header - -H "Accept: application/json"\
-H "Content-Type: application/json" -X POST\
--data "{\"name\":\"arrrg\"}"\
"http://localhost:8000/api/mobile/thing/?username=vikingosegundo&api_key=12345"
Run Code Online (Sandbox Code Playgroud)
我想自己补充一个答案.我没有将凭证作为GET参数添加,而是将其作为自定义HTTP标头传输,而不是Josh的解决方案 .
class CustomApiKeyAuthentication(ApiKeyAuthentication):
def is_authenticated(self, request, **kwargs):
username = request.META.get('HTTP_X_MYAPP_USERNAME') or request.GET.get('username')
api_key = request.META.get('HTTP_X_MYAPP_APIKEY') or request.GET.get('apikey')
if not username or not api_key:
return self._unauthorized()
try:
user = User.objects.get(username=username)
except (User.DoesNotExist, User.MultipleObjectsReturned):
return self._unauthorized()
request.user = user
return self.get_key(user, api_key)
class ThingResource(MopedModelResource):
creator = fields.ForeignKey(UserResource, 'creator', full = not True)
class Meta:
queryset = Thing.objects.all()
resource_name = "thing"
authentication = CustomApiKeyAuthentication()
authorization = ThingAuthorization()
Run Code Online (Sandbox Code Playgroud)
现在我们可以添加X-MYAPP-USERNAME和X-MYAPP-APIKEY请求.
这里是一个普通的telnet会话,使用GET
GET /api/mobile/thing/ HTTP/1.1
X-MYAPP-APIKEY: 12345
X-MYAPP-USERNAME: vikingosegundo
HTTP/1.0 200 OK
Date: Wed, 24 Aug 2011 19:37:05 GMT
Server: WSGIServer/0.1 Python/2.7.1
Content-Type: application/json; charset=utf-8
{"meta": {"limit": 20, "next": null, …
Run Code Online (Sandbox Code Playgroud)
以及POST的会话:
POST /api/mobile/thing/ HTTP/1.1
Content-Type: application/json
Content-Length: 49
X-MYAPP-APIKEY: 12345
X-MYAPP-USERNAME: vikingosegundo
{"name":"qwerty","creator":"/api/mobile/user/1/"}
HTTP/1.0 201 CREATED
Date: Wed, 24 Aug 2011 20:12:32 GMT
Server: WSGIServer/0.1 Python/2.7.1
Content-Type: text/html; charset=utf-8
Location: http://1.0.0.127.in-addr.arpa:8000/api/mobile/thing/8/
Run Code Online (Sandbox Code Playgroud)
而且,如果没有提供标题,我们也检查GET参数,这也有效:
http://localhost:8000/api/mobile/thing/?username=vikingosegundo;apikey=12345;format=json
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6954 次 |
| 最近记录: |