2012-11-16 29 views
11

में कोई csrftoken django मैं एक पोस्ट ajax अनुरोधकुकी

मुझे कोई csrftoken

मैं दस्तावेज़ पीछा किया की वजह से एक 403 मिला बनाने के लिए परीक्षण कर रहा हूँ, यह अभी भी काम नहीं।

मैंने पाया कुकी नामित csrftoken खाली

है इसका मतलब है कि $ .cookie ("csrftoken") लौट अशक्त

कोई मुझे कारण बता सकते हैं !!

कुकी में csrftoken सेट करने का तरीका

THX !!

+0

csrf_protect सजावट के साथ पहले एक समान समस्या थी। अगर आप किसी पृष्ठ से दूसरे यूआरएल (उदाहरण के लिए AJAX) पर पोस्ट कर रहे हैं और यदि आप @csrf_protect सजावट आदि का उपयोग कर रहे हैं तो सुनिश्चित करें कि आप दोनों दृश्य पोस्ट कर रहे हैं इस सजावट के लिए पोस्ट डेटा प्राप्त करने वाले यूआरएल से डेटा और यूआरएल। – sidarcy

+1

आपका विचार, आपका टेम्पलेट फॉर्म? –

उत्तर

15

मुझे लगता है कि आपको कोड प्रदान करना चाहिए कि आप अपने एचटीएमएल/जेएस कोड में सीएसआरएफ टोकन कैसे प्राप्त करते हैं और अपने मध्यवर्ती के लिए सेटिंग्स कैसे प्राप्त करते हैं।

सबसे पहले आपको यह जांचना चाहिए कि django.middleware.csrf.CsrfViewMiddleware चालू है।

मुझे एक समान समस्या थी, जब पायथन कोड में मैंने टोकन प्राप्त करने के लिए request.META.get('CSRF_COOKIE') का उपयोग किया था।

जब आप टेम्पलेट में इस टोकन का उपयोग करते हैं - {% csrf_token %} Django नोट करता है कि टोकन प्रदान किया गया था और कुकी को CsrfViewMiddleware.process_response में सेट किया गया था। यदि आपको टोकन मूल्य अन्य तरीकों से मिलता है तो Django इस ध्वज को याद करेगा। तो यह आपको एक टोकन उत्पन्न करेगा लेकिन संबंधित कुकी सेट नहीं करेगा।

मेरे पास कोड में 2 वर्कअराउंड हैं। आपको इसे अपने विचारों में जोड़ना चाहिए जिसका उपयोग जेएस कोड के साथ टेम्पलेट जेनरेट करने के लिए किया जाता है।

1. आप CSRF कुकी सेट करने के लिए Django मजबूर कर सकते हैं:

# Force updating CSRF cookie 
request.META["CSRF_COOKIE_USED"] = True 

2. Django CSRF_COOKIE_USED स्वतः निर्धारित अगर आप get_token

from django.middleware.csrf import get_token 
# don't use direct access to request.META.get('CSRF_COOKIE') 
# in this case django will NOT send a CSRF cookie. Use get_token function 
csrf_token = get_token(request) 

इस समाधान में से हर एक फोन अलग से काम करना चाहिए। मैं get_token

+0

मुझे वास्तव में खेद है, मैं इसे भूल गया। आपके उत्तर के लिए धन्यवाद। –

13

का उपयोग करने की सलाह देता हूं शायद आप ensure_csrf_cookie देखें सजावट (Django 1.4 के बाद उपलब्ध) का उपयोग करना चाहते हैं। यह कुकी सेट करेगा भले ही आप {{ csrf_token }} टेम्पलेट टैग का उपयोग न करें।

+1

यह विधि मेरे लिए अच्छी तरह से काम किया! – Max

3

मुझे एक ही समस्या थी ($। कुकी ('csrftoken') 'अपरिभाषित' लौटा)।

समस्या मेरे Django विन्यास में था, मैं निम्नलिखित पंक्ति टिप्पणी की है और यह काम करता है:

#CSRF_COOKIE_HTTPONLY = True # Prevent client-side JavaScript access to the CSRF cookie 
+0

हाँ, http-only कुकी ब्राउज़ में जावास्क्रिप्ट द्वारा एक्सेस नहीं कर सकती है। –

2

o_c's answer पर विस्तार: CSRF_COOKIE_HTTPONLY लाइन टिप्पणी करके, csrf_token मूल्य फ़ायरफ़ॉक्स फ़ायरबग में (अब 'अनिर्धारित' है) और 'वास्तविक' मान के रूप में दिखाया गया है, उदाहरण के लिए 'qGuPe2Q7 ... आदि'।

अजाक्स अनुरोध अब 403 Forbidden त्रुटि से अस्वीकार नहीं किया गया है और सही ढंग से निष्पादित किया गया है (बशर्ते कि csrf_token AJAX शीर्षलेख में सेट हो)।

 $.ajaxSetup({ 
      beforeSend: function(xhr, settings) { 
       if (!csrfSafeMethod(settings.type) && !this.crossDomain) { 
       xhr.setRequestHeader("X-CSRFToken", csrftoken); 
       } 
      } 
     }); 
1

सबसे पहले, अगर आप आवेदन को डिजाइन कर रहे हैं, यह हमेशा बेहतर एक शीर्षक में या पोस्ट अनुरोध के बजाय एक कुकी में टोकन CSRF उपयोग करने के लिए है, क्योंकि:

  • सभी रूपों चाहिए मूल्य को अपने एचटीएमएल में गतिशील रूप से जोड़ा गया है। कोई AJAX पोस्ट में मूल्य भी शामिल होना चाहिए।
  • कुकी प्रत्येक अनुरोध के लिए सबमिट की जाएगी (यानी छवियों, सीएसएस, जेएस, आदि के लिए सभी जीईटी, जो सीएसआरएफ प्रक्रिया में शामिल नहीं हैं) बढ़ते अनुरोध आकार।

आप Django में कुकीज़ के उपयोग के लिए बाध्य करना चाहते हैं, तो आप हमेशा किए जा सकेंगे:

request.META["CSRF_COOKIE_USED"] = True 
अपनी परियोजना में

यदि आप {% csrf_token%} उपयोग नहीं कर रहे कहीं भी। [प्रलेखन] [1] के अनुसार, आपको कुछ और करने की आवश्यकता नहीं है, लेकिन एक साधारण जावास्क्रिप्ट कोड लिखें। असल में यह सच नहीं है। आपको प्रत्येक दृश्य में "request.META['CSRF_COOKIE_USED'] = True" लाइन डालना होगा (या उपयुक्त सजावट लिखें)।

संबंधित मुद्दे