Django:仅在某些条件适用时才进行CSRF检查

时间:2014-04-16 10:25:19

标签: django authentication csrf

我有一个简单的REST API,需要从Web应用程序和远程服务访问。

远程服务通过包含API密钥的自定义HTTP标头进行身份验证。

如何保护该API,使得来自Web浏览器的请求受CSRF保护,但在通过API密钥进行身份验证时未执行CSRF检查?或者,一般来说,如何为特定视图上的某些请求启用CSRF保护,而不是其他请求?

目前,我有一个装饰器,用于检查API密钥的请求,并以这种方式对API用户进行身份验证:

# Regular auth
if request.user.is_authenticated():
    # DO CSRF verification, then continue calling the view

elif 'HTTP_X_API_KEY' in request.META:
    api_key = request.META['HTTP_X_API_KEY']
    user = authenticate(username=settings.API_USER_NAME, password=api_key)
    login(request, user)
    # If user is authenticated and autzorized, continue calling the view
    # but WITHOUT invoking CSRF protection

上述问题是,我只希望为普通用户提供CSRF保护,而不是API用户。

1 个答案:

答案 0 :(得分:0)

好的,所以在经过一些修补之后,解决方案是禁用CSRF中间件并为需要CSRF保护的所有情况启用csrf_protect

这适用于API的特殊情况,因为无论如何都要对每个调用进行修饰,因此忽略某些视图的风险可以忽略不计。

然而,的工作原理是使用csrf_exempt。问题是装饰器只在视图上设置csrf_exempt属性,如果你有多个装饰器,可能会再次被屏蔽,即使你使用functools.wraps

此外,由于csrf_exempt在视图中放置了一个属性,因此无法根据请求的内容动态启用或禁用该属性 - 这实际上是非常静态的事情。