我正在使用django rest框架通过IOS执行API调用 我收到以下错误 “CSRF失败:未设置CSRF cookie。”
这是我的django API代码:
class LoginView(APIView):
"""
List all snippets, or create a new snippet.
"""
@csrf_exempt
def get(self, request, format=None):
startups = Startup.objects.all()
serializer = StartupSerializer(startups, many=True)
return Response(serializer.data)
@csrf_exempt
def post(self, request, format=None):
profile = request.POST
....
我该怎么办?
答案 0 :(得分:14)
如果有人仍然关注这个问题,直接的答案是你需要在view方法本身上使用装饰器。 get
类上定义的post
和APIView
方法只告诉DRF实际视图应该如何运行,但django路由器期望的视图方法实际上不会实例化,直到您调用{{ 1}}。
因此,解决方案是将LoginView.as_view()
装饰器添加到csrf_exempt
。它可能如下所示:
urls.py
但是,正如Mark上面指出的那样,csrf保护对于防止会话被劫持很重要。我自己没有使用iOS,但我会考虑使用django的cookie-based csrf tokens。您可以使用#file: urls.py
from django.conf.urls import patterns, url
from django.views.decorators.csrf import csrf_exempt
import views
urlpatterns = patterns('',
url('^login/$', csrf_exempt(views.LoginView.as_view())),
...
)
装饰器使django发送带有响应的ensure_csrf_cookie
Cookie,只要您将该标记包含为csrftoken
标头,您的POST
请求就会生效
答案 1 :(得分:3)
您遇到的问题是用于处理视图的django使用的是as_view()
方法将返回的内容,而不是直接方法get()
或post()
。
因此,您应该通过以下方式之一装饰基于类的视图:
urlpatterns = patterns('', url('^login/$', csrf_exempt(views.LoginView.as_view())), ... )
dispatch()
方法(pre django 1.9)from django.utils.decorators import method_decorator class LoginView(APIView): @method_decorator(csrf_exempt) def dispatch(self, *args, **kwargs): ...
from django.utils.decorators import method_decorator @method_decorator(csrf_exempt, name='dispatch') class LoginView(APIView): ...
答案 2 :(得分:2)
对于GET,您不应该修改数据,因此不需要CSRF。
如果您使用POST修改数据,那么如果您使用基于会话的身份验证,则应该有CSRF。否则,你正在打开一个安全漏洞。即使您认为您的Django服务器将要为iPhone应用程序提供服务,但没有什么可以阻止您的应用程序嗅探流量到服务器的数据包,然后使用其他类型的Web客户端逆向工程访问服务器。因此,Django Rest Framework在某些情况下需要CSRF。这在Django rest framework documentation中提到。
此POST要求的路径是不使用会话身份验证。例如,您可以通过HTTPS使用BasicAuthentication。使用此身份验证机制,您应该使用HTTPS来防止凭据在每个请求中以明文形式传递。
答案 3 :(得分:2)
我有同样的问题。我的问题是我忘记将.as_view()
放在MyAPIView
的urls.py中。所以它必须像:
url(r'$', GetLikesAPI.as_view(), name='list')
不是:
url(r'$', GetLikesAPI, name='list')
答案 4 :(得分:1)
在我的情况下,它发生了,因为我发送了请求到url =' http://example.com/list/5'最后没有斜线。当我将网址更改为url =' http://example.com/list/5/'一切都开始奏效了。
答案 5 :(得分:0)
这是一个老问题,但我们最近遇到了一些问题。
除非使用会话身份验证,否则DRF会默认禁用CSRF。默认情况下,NSURLconnection设置为处理cookie。您需要明确告诉iOS应用不使用cookie。然后,如果需要,您可以继续使用会话身份验证,而不必让csrf免除您的观点。
答案 6 :(得分:0)
urlpatterns = patterns('',
url('^login/$', csrf_exempt(views.LoginView.as_view())),
...
)
专家。我有同样的错误,花了很多时间才发现: 1)我有另一个'登录'的路由器,我错过了'$'。我的意思是有时候你会忘记路由中的某些内容并得到这个错误。