简体   繁体   English

“禁止(CSRF 令牌丢失或不正确。):”使用 Django 和 JS

[英]“Forbidden (CSRF token missing or incorrect.):” using Django and JS

I'm doing a POST request using Axios in my JS code to send some information to my locally hosted Django server.我在我的 JS 代码中使用 Axios 执行 POST 请求,以将一些信息发送到我本地托管的 Django 服务器。 I have {% csrf_token %} in my html code form but don't know how to send the csrf token using Axios.我的 html 代码表单中有 {% csrf_token %},但不知道如何使用 Axios 发送 csrf 令牌。

I get this error in the terminal: "Forbidden (CSRF token missing or incorrect.): /api/scoring/submit_score_details".我在终端中收到此错误:“禁止(CSRF 令牌丢失或不正确。):/api/scoring/submit_score_details”。

How do I correctly insert the csrf token in my axios post?如何在我的 axios 帖子中正确插入 csrf 令牌? Right now, I don't think JS can read {{ csrf_token }} as I have it.现在,我不认为 JS 可以像我一样读取 {{ csrf_token }}。 I've been searching Stack but it seems most people are using jQuery or some other type of JS.我一直在搜索 Stack,但似乎大多数人都在使用 jQuery 或其他一些类型的 JS。

To save space I didn't post what the variables in the payload are but they're all just strings.为了节省空间,我没有发布有效负载中的变量是什么,但它们都只是字符串。

I can get the error to go away if I put @csrf_exempt above the my function in the views.py file.如果我将@csrf_exempt 放在views.py 文件中的function 上方,我可以得到go 的错误。

 { let payload = { "csrfmiddlewaretoken": "{{ csrf_token }}", "math_problem": problem, "user_answer": userInput, "true_answer": correctAnswer, "question_status": questionStatus, } console.log(payload); axios.post('../api/scoring/submit_score_details', payload) }
 <div class="col text-center"> <button id="start" type="button" class="btn btn-primary btn-lg"> New Problem </button> <p id="math_problem"></p> <form id="inputForm" method="POST"> {% csrf_token %} <input id="user_input" autocomplete="off" class="form-control form-control-lg" type="text" placeholder="Type your answer here"> <input id="correct_answer" type="hidden"> </form> <br> <button id="result_check" type="button" class="btn btn-primary btn-lg">Check</button> <script src={% static 'js/game_logic.js' %}></script> </div>

 { let payload = { "csrfmiddlewaretoken": "{{ csrf_token }}", "math_problem": problem, "user_answer": userInput, "true_answer": correctAnswer, "question_status": questionStatus, } console.log(payload); axios.post('../api/scoring/submit_score_details', payload) }
 <form id="inputForm" method="POST"> {% csrf_token %} <input id="user_input" autocomplete="off" class="form-control form-control-lg" type="text" placeholder="Type your answer here"> <input id="correct_answer" type="hidden"> </form>

So I ended up doing some googling and asking a friend.所以我最终做了一些谷歌搜索并问了一个朋友。 We came up with a solution.我们想出了一个解决方案。

We had to add two lines of code to make things work:我们必须添加两行代码才能使事情正常进行:

axios.defaults.xsrfCookieName = 'csrftoken';
axios.defaults.xsrfHeaderName = 'X-CSRFToken';

We also got rid of the 'payload' variable and just put everything in the Axios code.我们还去掉了“有效负载”变量,将所有内容都放入 Axios 代码中。

 { axios.defaults.xsrfCookieName = 'csrftoken'; axios.defaults.xsrfHeaderName = 'X-CSRFToken'; axios.post('../api/scoring/submit_score_details', { "math_problem": problem, "user_answer": userInput, "true_answer": correctAnswer, "question_status": questionStatus, }); console.log(`Problem:${problem}, User Input: ${userInput}, Correct Answer: ${correctAnswer}, Question Status: ${questionStatus}` ); };
 <div class="col text-center"> <button id="new_problem_button" type="button" class="btn btn-primary btn-lg"> New Problem </button> <p id="math_problem"></p> <form id="inputForm" method="POST"> {% csrf_token %} <input id="user_input" autocomplete="off" class="form-control form-control-lg" type="text" placeholder="Type your answer here"> <input id="correct_answer" type="hidden"> </form> <br> <button id="result_check" type="button" class="btn btn-primary btn-lg">Check</button> <script src={% static 'js/game_logic.js' %}></script> </div>

Here's a link that helped us.这是一个帮助我们的链接。

Is is possible your Axios code is being created before the csrf_token is being rendered in the page (by the django template)?是否可能在页面中呈现 csrf_token 之前创建您的 Axios 代码(通过 django 模板)?

Try something like this early on in your js code:在你的 js 代码中尽早尝试这样的事情:

var my_token = '{{ csrf_token }}';

then when you call Axios, send this value, instead of rendering {{ csrf_token }} inline, so something like this:然后当你调用 Axios 时,发送这个值,而不是渲染 {{ csrf_token }} 内联,所以是这样的:

{
    let payload = {
        "csrfmiddlewaretoken": my_token,
        "math_problem": problem,
        "user_answer": userInput,
        "true_answer": correctAnswer,
        "question_status": questionStatus,
    }
    console.log(payload);
    axios.post('../api/scoring/submit_score_details', payload)
}

I'm also curious as to whether you saw your csrf token being printed to the console in the code you showed (from printing out payload), since this would indicate whether it was being sent or not.我也很好奇您是否在显示的代码中看到您的 csrf 令牌被打印到控制台(从打印出有效负载),因为这将表明它是否正在发送。

If the csrf_token was being sent, it is possible there may be some other issue going on with the app, but once you have the token in my_token, you can print it out and see that it's set appropriately and work from there.如果正在发送 csrf_token,则应用程序可能会出现其他问题,但是一旦您在 my_token 中获得了令牌,您就可以将其打印出来并查看它是否已正确设置并从那里开始工作。

Ok, looking back at the discussion, I think I might know what's going on here...好吧,回头看看讨论,我想我可能知道这里发生了什么......

Maybe you've added the "{{ csrf_token }}" inside your JS (stored in static code somewhere) -- this won't work, since as you pointed out, JS knows nothing about django templates.也许您在 JS 中添加了“{{ csrf_token }}”(存储在某处的 static 代码中)——这不起作用,因为正如您所指出的,JS 对 django 模板一无所知。

The way to do this would be to change your JS code to use a JS variable (such as my_token).这样做的方法是更改您的 JS 代码以使用 JS 变量(例如 my_token)。

{
    let payload = {
        "csrfmiddlewaretoken": my_token, // populated later within form
        "math_problem": problem,
        "user_answer": userInput,
        "true_answer": correctAnswer,
        "question_status": questionStatus,
    }
    console.log(payload);
    axios.post('../api/scoring/submit_score_details', payload)
}

This my_token value will be supplied later (within your form) before the Axios call is made.这个 my_token 值将在 Axios 调用之前提供(在您的表单中)。 To do this, add this in your form:为此,请在您的表单中添加:

<script>
    // This will be rendered by Django to get the actual string into my_token
    var my_token = "{{ csrf_token }}"; 
</script>

Then, when your Axios call is made (by clicking a button or on a timer or whatever), this global variable should be correctly set and used.然后,当您调用 Axios 时(通过单击按钮或计时器或其他方式),应正确设置和使用此全局变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 Django 中的 ajax POST 期间禁止(CSRF 令牌丢失或不正确。) - Forbidden (CSRF token missing or incorrect.) during ajax POST in Django 禁止(CSRF 令牌丢失或不正确。) | Django 和 AJAX - Forbidden (CSRF token missing or incorrect.) | Django and AJAX (缺少CSRF令牌或不正确。)在Django中使用AJAX - (CSRF token missing or incorrect.) using AJAX in Django 尽管正确发送令牌,Django 服务器仍报告“禁止(CSRF 令牌丢失或不正确。)”? - Django server reporting "Forbidden (CSRF token missing or incorrect.)" despite sending token correctly? 禁止(CSRF令牌丢失或不正确。)-即使已包含 - Forbidden (CSRF token missing or incorrect.) - even though it's included 禁止(CSRF令牌丢失或不正确。)Django如何解决?用我的代码 - Forbidden (CSRF token missing or incorrect.) Django how to solve?WITH MY CODE 如何更正 django 中的以下代码,它给出错误“禁止(CSRF 令牌丢失或不正确。)” - How do I correct the following code in django, It's give an error “Forbidden (CSRF token missing or incorrect.)” 用yui设置Django CSRF_TOKEN,但控制台显示“ django.request禁止(CSRF令牌丢失或不正确。)”。 - Set Django CSRF_TOKEN with yui, but console says 'django.request Forbidden (CSRF token missing or incorrect.)' 禁止(CSRF 令牌丢失或不正确。)如何将 CSRF 令牌从前端发送到后端? - Forbidden (CSRF token missing or incorrect.) how to send CSRF token from frontend to backend? 详细信息:“CSRF失败:CSRF令牌丢失或不正确。” - detail: “CSRF Failed: CSRF token missing or incorrect.”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM