Ajax中的CSRF令牌 - Post Api

时间:2017-09-01 21:44:54

标签: javascript jquery python ajax django

我的问题是我使用Django创建了一个POST API,我正在调用一个按钮。但每次它都会给出CSRF令牌错误。每次邮件请求返回403.我不知道我哪里出错了。

我正在编写下面的代码。其余代码可以找到in this repo

views.py中的API

class UserList(APIView):

def post(self, request, format=None):
    serializer = User.objects.create()
    serializer = UserSerializer(data=request.DATA)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

这是我在AJAX中进行的API调用

// CSRF Token ERROR
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');

//Function for the Post Api Call
var data = '{"inputs":[{"data":{"name":{"email"::{"msg"::{"enc_msg"}}}]}'
$("encrypt_button").on("click", function(e){
e.preventDefault();
$.ajax({
    'type': 'POST',
    'url': '/users',
    'data': {
        'csrfmiddlewaretoken' : csrftoken,
        'data': data,
    },
    success: function (response) {
        console.log("HIGH");
        console.log(response.outputs);
    },
    error: function (xhr) {
        console.log("HIGH");
        console.log(xhr);
    }
})
})

这在我的Urls.py

urlpatterns = [
url('users', views.UserList.as_view()),
url('', main_view)
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

这是我的index.html

{% load staticfiles %}

<!DOCTYPE html>
<html lang="en-Us">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<title>Vignere Cypher</title>
</head>

<body>

<div class="container">
    <h1>Vignere Cypher</h1>


    <div class="main">
    <form class="main" method="post">
        {% csrf_token %}
        <div class="name">
            <label for="name">Your Name: </label>
            <input id="name" type="text" name="name" value="{{ name }}">
        </div>
        <div class="email">
            <label for="email">Email (To whom you want to send this message): </label>
            <input id="email" type="text" name="email" value="{{ email }}">
        </div>
        <div class="message">
            <label for="message" id="lol">Message to Encrypt: </label>
            <textarea rows="5" cols="50" id="message" type="text" name="message" value="{{ message }}"></textarea>
        </div>
        <div class="key_input">
            <label id="lol3" for="key">Enter the key:</label>
            <textarea rows="1" cols="30" type="text" name="key" placeholder="Enter key" id="key_input" /></textarea>
            <input type="button" value=" Encrypt " id="encrypt_button" onclick="doCrypt(false);UserAction();">
            <input type="button" value=" Decrypt " id="encrypt_button1" onclick="doCrypt(true)">
            <input type="button" value=" Random Key " id="encrypt_button2" onclick="">
        </div>
        <div class="enc_message">
            <label for="enc_message" id="lol1">Encrypted Message: </label>
            <textarea rows="5" cols="50" id="enc_message" type="text" name="enc_message" value="{{ enc_message }}"></textarea>
        </div>
        <input type="submit" value="Submit">

    </div>
    </form>
</div>
<script type="text/javascript" src="{% static 'main.js' %}"> </script>
</html>

更新

尝试下面给出的解决方案后,错误是不同的。现在正在收到请求而不是帖子。

Image

2 个答案:

答案 0 :(得分:0)

直接从Django文档(https://docs.djangoproject.com/en/1.11/ref/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');

如果在设置模块中将CSRF_USE_SESSION设置为False,则上述功能用于获取CSRF令牌。如果此设置设置为True,则可以使用上面链接的文档中的其他解决方案。

答案 1 :(得分:0)

您在API调用中的数据缺少'csrfmiddlewaretoken' : csrftoken var csrftoken = getCookie('csrftoken');定义如下

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;
    }

在定义上述内容后,将'csrfmiddlewaretoken' : csrftoken添加到var data = ... `