在视图GET方法上使用@csrf_protect

Dan*_*anH 1 django django-views django-csrf python-2.7 django-1.5

我的大部分GET请求都是由Angular触发的,这样可以很容易地在头文件中设置CSRF令牌.这已经开箱即用于POST请求,但是我想知道我是否也可以对GET请求使用CSRF保护.

我最初的直觉是@csrf_protect在View的get方法之前添加,例如:

class ProjectView(View):
    @csrf_protect
    def get(self, request, *args, **kwargs):
        ...
Run Code Online (Sandbox Code Playgroud)

但是这会产生错误:

AttributeError at /project
'ProjectView' object has no attribute 'COOKIES'

File "c:\Apps\msysgit\simpletask\lib\site-packages\django\middleware\csrf.py" in process_view
  95.                 request.COOKIES[settings.CSRF_COOKIE_NAME])
Run Code Online (Sandbox Code Playgroud)

所以我猜测有一些POST请求提供了哪些GET请求没有.有一个更好的方法吗?

此外,在任何人提到应该通过POST请求提取所有敏感信息之前(我最近已经看过几次),我试图坚持使用GET的原因是我正在尝试根据RESTful指南构建,这意味着GET请求用于提取数据,POST用于新记录,PUT用于更新,DELETE用于删除数据.

编辑:

由于似乎有一种情绪我不应该尝试上述内容,而我现在确实有点同意,我试图阻止的漏洞在这三个链接中讨论:

Bur*_*lid 7

我不认为您完全理解CSRF实际上保护的内容.CSRF利用网站对用户浏览器的信任; 通过利用允许攻击者代表用户运行命令的会话cookie.

该站点信任该请求,因为它尚未使浏览器的会话cookie过期.这就是为什么在大多数CSRF缓解技术中,为每个具有副作用的请求生成唯一的OTP.攻击者不会知道为OTP生成的密钥,因此无法伪造合法请求.

对于所有具有副作用的URL(如POST,PUT,DELETE),您需要CSRF.对于GET而言,拥有它没有任何意义,因为GET请求 - 如果你正确地做REST - 应该是幂等的 - 如果多次运行,它们返回相同的结果,它们不应该有任何副作用.

CSRF保护不会阻止信息泄露或中间人攻击.因此,如果您要保护敏感信息,请使用HTTPS.要防止不受管制地使用您的API,请使用身份验证和授权.


小智 5

你需要使用method_decorator

https://docs.djangoproject.com/en/1.4/topics/class-based-views/#decorating-the-class

所以你的代码将是

class ProjectView(View):`
    @method_decorator(csrf_protect)
    def get(self, request, *args, **kwargs):
Run Code Online (Sandbox Code Playgroud)

[编辑] 但是csrf_protect只会检查 POST 请求(它有 `if request.method == 'POST' 检查),所以你必须自己实现一些东西。