django rest框架csrf令牌丢失或不正确

时间:2017-05-04 12:33:57

标签: django django-rest-framework django-rest-auth

你好我正在使用django rest-auth我在/ password / change /中有这个问题它总是返回csrf令牌丢失或不正确的问题: 我正在开发一个Android应用程序的请求 我的设置是:

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',

'rest_framework',
'rest_framework.authtoken',

'rest_auth',
'rest_auth.registration',

'allauth',
'allauth.account',
'allauth.socialaccount',

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    )
}

版本: django的静止-AUTH == 0.9.1

djangorestframework == 3.6.2

6 个答案:

答案 0 :(得分:3)

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework.authentication.TokenAuthentication',
)
}

从DEFAULT_AUTHENTICATION_CLASSES中移除'rest_framework.authentication.SessionAuthentication',如果仍需要DRF的可浏览api视图,请在chrome中使用ModHeader

答案 1 :(得分:1)

在阅读了django rest framework官方的文档后,来自@Todor comment的很多帮助我意识到我应该只将TokenAuthentification放入其余的身份验证类中,因为sessionAuthentication期望在请求中有一个csrf值,但android不能给出,所以我在每个请求中都使用doc中的令牌,就是这样!

答案 2 :(得分:0)

当我尝试在Apache服务器上托管网站时出现此错误。 如果我在没有Apache服务器(python manage.py runserver)的情况下运行,一切都很好。

要解决此错误: 打开Apache配置文件-httpd.conf 添加以下行:

WSGIPassAuthorization On

答案 3 :(得分:0)

这是我的快速解决方案,除非您将其余的框架回购与您的更改一起使用,否则它不适用于生产……而且很好地,它禁用了SessionAuthentication的功能。

如果您打算将api与无浏览器的前端(如移动应用程序)一起使用,则不允许进行跨站点请求(因为没有浏览器可以从中进行请求,即应用将无法打开其他人发送给您的链接/您传统上无法在其中浏览网络)然后就这么简单:

要删除此功能,请转到rest_framework网站包。它的内部是一个authentication.py文件,内部有一个名为“ SessionAuthentication”的类。在这里,有一个force_csrf()函数,通过在请求中不存在csrf令牌时引发异常来强制csrf。只需注释掉它的身体,它将不再关心csrf。

这是authentication.py SessionAuthentication类的外观,请执行以下操作:

class SessionAuthentication(BaseAuthentication):

    def authenticate(self, request):
        """
        Returns a `User` if the request session currently has a logged in user.
        Otherwise returns `None`.
        """

        # Get the session-based user from the underlying HttpRequest object
        user = getattr(request._request, 'user', None)

        # Unauthenticated, CSRF validation not required
        if not user or not user.is_active:
            return None

        self.enforce_csrf(request)

        # CSRF passed with authenticated user
        return (user, None)

    def enforce_csrf(self, request):
        """
        Enforce CSRF validation for session based authentication.
        """
        ##### Comment Out Below:  ###########
        # check = CSRFCheck()
        # # populates request.META['CSRF_COOKIE'], which is used in process_view()
        # check.process_request(request)
        # reason = check.process_view(request, None, (), {})
        # if reason:
        #     # CSRF failed, bail with explicit error message
        #     raise exceptions.PermissionDenied('CSRF Failed: %s' % reason)

因此,如果您想知道这是否是个坏主意,因为在大多数情况下,所有请求都是在移动应用程序内部有意发出的,或者是由移动应用程序专门控制的,因此它不能在与浏览器。用户很难不小心跟随链接或脚本。请注意,这不能完全补救该漏洞,但是发生这种情况的可能性极小,而且很可能不会直接通过移动应用程序发生

答案 4 :(得分:0)

我想使用 SessionAuthentication 使当前用户处于休息视图,我解决了它在每个请求中发送带有令牌值的授权标头,我也使用JSON Web令牌认证

答案 5 :(得分:-1)

解决方案很简单:您需要在提出请求时添加CSRF token。您将如何做到这一点,具体而言,我们无法回答,因为我们不知道您是如何提出请求的。即显示一些代码