Django用户注册和CSRF令牌

时间:2016-03-12 12:18:47

标签: django django-rest-framework registration django-csrf

我正在制作像这样的用户注册。我已经允许任何许可来提出此请​​求。但是,当我从邮递员那里发帖时,我得到了

"detail": "CSRF Failed: CSRF token missing or incorrect."

我该怎么办?

class RegistrationView(APIView):
    """ Allow registration of new users. """
    permission_classes = (permissions.AllowAny,)

    def post(self, request):
        serializer = RegistrationSerializer(data=request.DATA)

        # Check format and unique constraint
        if not serializer.is_valid():
            return Response(serializer.errors,\
                        status=status.HTTP_400_BAD_REQUEST)
        data = serializer.data

    # u = User.objects.create_user(username=data['username'],
    #                              email=data['email'],
    #                              password='password')

    u = User.objects.create(username=data['username'])
    u.set_password(data['password'])
    u.save()

    # Create OAuth2 client
    name = u.username
    client = Client(user=u, name=name, url='' + name,\
            client_id=name, client_secret='', client_type=1)
    client.save()
    return Response(serializer.data, status=status.HTTP_201_CREATED)

3 个答案:

答案 0 :(得分:1)

CSRFpermission classes无关。 APIView默认为csrf-exempt。关于APIViewcsrf here

的非常好的讨论
  

因为默认情况下可以从浏览器(需要CSRF保护)或服务​​器(不需要CSRF保护)使用API​​Views,因此关闭CSRF保护。但是,默认情况下,APIView还有一个名为SessionAuthentication的身份验证类。如果当前请求对象包含活动用户,则此类将动态地重新应用django的CSRF中间件。

所以很可能因为你已经logged in而得到了这个错误。

答案 1 :(得分:0)

您可以在此处找到更多详细信息: https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/

形式:

<form action="." method="post">{% csrf_token %}

AJAX:

从cookie获取CSRF:

// using jQuery
function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
var csrftoken = getCookie('csrftoken');

JQuery AJAX:

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
function sameOrigin(url) {
    // test that a given url is a same-origin URL
    // url could be relative or scheme relative or absolute
    var host = document.location.host; // host + port
    var protocol = document.location.protocol;
    var sr_origin = '//' + host;
    var origin = protocol + sr_origin;
    // Allow absolute or scheme relative URLs to same origin
    return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
        (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
        // or any other URL that isn't scheme relative or absolute i.e relative.
        !(/^(\/\/|http:|https:).*/.test(url));
}
$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
            // Send the token to same-origin, relative URLs only.
            // Send the token only if the method warrants CSRF protection
            // Using the CSRFToken value acquired earlier
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});

答案 2 :(得分:-1)

在使用会话身份验证时,通常需要检查CSRF。因此,您必须在X-CSRFToken标头中传递CSRF令牌。

由于您实际上尚未登录,因此必须使用csrf_exempt装饰器。

from django.views.decorators.csrf import csrf_exempt

class RegistrationView(APIView):
    permission_classes = (permissions.AllowAny,)

    @csrf_exempt
    def post(self, request):
        # Do what needs to be done
        pass