2010-09-21 15 views
10

मैंने हाल ही में Django 1.2.3 में अपग्रेड किया है और मेरे अपलोड फॉर्म अब टूटा हुआ है। जब भी मैं अपलोड करने का प्रयास करता हूं, मुझे "सीएसआरएफ सत्यापन विफल हो जाता है। अनुरोध निरस्त कर दिया गया।" त्रुटि संदेश।मैं जावास्क्रिप्ट द्वारा जेनरेट किए गए HTML फॉर्म में Django 1.2 के CSRF टोकन को कैसे शामिल करूं?

इस विषय पर Django's documentation पढ़ने के बाद, यह बताता है कि मुझे अपने टेम्पलेट में HTML <form> के भीतर {% csrf_token%} टेम्पलेट टैग जोड़ने की आवश्यकता है। दुर्भाग्य से, मेरे <form> जावास्क्रिप्ट के माध्यम से उत्पन्न होता है (विशेष रूप से, एक पैनल पर ExtJs की "html" प्रॉपर्टी)।

लंबी कहानी छोटी, मैं अपने <form> पर आवश्यक सीएसआरएफ टोकन टैग कैसे जोड़ूं जब मेरा <form> Django टेम्पलेट में शामिल नहीं है?

उत्तर

13

एक और विकल्प the Django docs में दिखाए गए कुकी/हेडर आधारित समाधान को अनुकूलित करने के लिए होगा - यदि आपके पास बहुत सारे टेम्पलेट हैं और आप प्रत्येक को बदलना नहीं चाहते हैं तो बेहतर विकल्प।

बस अपने overrides.js में निम्नलिखित स्निपेट ड्रॉप (या जहाँ भी आप वैश्विक संशोधनों डाल):

Ext.Ajax.on('beforerequest', function (conn, options) { 
    if (!(/^http:.*/.test(options.url) || /^https:.*/.test(options.url))) { 
    if (typeof(options.headers) == "undefined") { 
     options.headers = {'X-CSRFToken': Ext.util.Cookies.get('csrftoken')}; 
    } else { 
     options.headers.extend({'X-CSRFToken': Ext.util.Cookies.get('csrftoken')}); 
    }       
    } 
}, this); 

(संपादित करें: Ext पहले से ही कुकी पढ़ने समारोह है, कोई जरूरत नहीं इसकी नक़ल करने की)

+0

क्या मुझे अपने गतिशील रूप से जेनरेट किए गए फॉर्म में कुछ भी करने/जोड़ने की ज़रूरत है? – john2x

+1

@ जॉन 2x: नहीं, आपको बस अपने overrides.js में कोड डालना होगा। यदि आप overrides.js की अवधारणा से परिचित नहीं हैं, तो निम्न ब्लॉग एक अच्छी शुरुआत है: http://edspencer.net/2009/07/extoverride-monkey-patching-ext-js.html – chrisv

+0

+1। शानदार, मैं उसी जवाब पर सोच रहा था जब मुझे यह जवाब मिला! – Swanand

9

सबसे आसान तरीका है अपने पृष्ठ पर एक छिपे हुए फॉर्म को django का उपयोग करना जो कुछ भी नहीं करता है। फिर फ़ॉर्म को लाने के लिए जावास्क्रिप्ट का उपयोग करें और विशेष रूप से फॉर्म के टोकन इनपुट को बाहर निकालें। अंत में, उस टोकन इनपुट को उस रूप में डालें या कॉपी करें जिसे आप गतिशील रूप से उत्पन्न कर रहे हैं।

यहां दो उदाहरण दिए गए हैं कि आप जावास्क्रिप्ट के लिए टोकन कैसे प्रकाशित कर सकते हैं।

<input id="csrf_token" value="{{ csrf_token }}"/> 

<script type="text/javascript"> 
var CSRF_TOKEN = document.getElementById('csrf_token').value; 
</script> 

या

<script type="text/javascript"> 
var CSRF_TOKEN = "{{ csrf_token }}"; 
</script> 
+0

की आवश्यकता है आपको एक उदाहरण दे सकते हैं? – Huuuze

+0

नीचे वोट क्यों? –

+0

@Huuuze: कहीं भी टेम्पलेट में '{csrf_token}' डालें, और इसे फ़ॉर्म बिल्डिंग के दौरान जावास्क्रिप्ट के साथ पार्स करें। –

0

दृश्य आपको POST आईएनजी भी GET पर प्रतिक्रिया के लिए है? उसमें जेएस कोड प्रश्न में देखने के लिए GET अनुरोध कर सकता है और सीएसआरएफ टोकन निकालने के लिए उत्पादन को पार्स कर सकता है। मेरा जेएस-एफ कमजोर है और मुझे यकीन नहीं है कि आप क्लाइंट साइड से पार्सिंग कैसे कर सकते हैं।

के लिए संबंधित उदाहरण this question देखें। इस मामले में उपयोगकर्ता एक पाइथन लिपि का उपयोग करके POST का प्रयास कर रहा था और उसी कारण से विफल रहा था। समाधान वही था, सिवाय इसके कि उसे इसे जावास्क्रिप्ट की बजाय पाइथन लिपि से करना था।

1

एक बेहतर समाधान जेएस फ़ाइल के कोड को दृश्य/टेम्पलेट से उत्पन्न करना है।

फिर, ध्यान में रखते हुए आप CSRF तो जैसे संदर्भ में फिर सेट कर सकते हैं टोकन ...

from django.core.context_processors import csrf 
context = RequestContext(request) 
context.update(csrf(request)) 

, टेम्पलेट में, आप {{ csrf_token }} उपयोग कर सकते हैं CSRF टोकन के कच्चे मूल्य प्राप्त करने के , और फिर csrfmiddlewaretoken नाम के साथ अपने फ़ॉर्म में एक छुपा फ़ील्ड बनाने के लिए इसका उपयोग करें।

0

यह आदर्श नहीं हो सकता है, लेकिन यह मेरे लिए सबसे तेज़ समाधान था। "बॉडी" के नीचे मेरे मुख्य टेम्पलेट में, मैंने अपनी लाइब्रेरी में एक जावास्क्रिप्ट फ़ंक्शन जोड़ा।

<script type="text/javascript"> 
    MyToolkit.Utils.getCSRFToken = function() { 
     return "{% csrf_token %}"; 
    }; 
</script> 
+0

देखें कि टैग एक छिपा div देता है। मुझे लगता है कि आपका मतलब {{csrf_token}} था – Tom

0

यह सीएसआरएफ टोकन या ऑटो की आवश्यकता होने पर ऑटो उत्पन्न करेगा। यह पृष्ठ पर सभी फॉर्म जमा करने को संभालेगा। यदि आपके पास ऑफ़-साइट फॉर्म हैं तो आपको यह सुनिश्चित करना होगा कि वे इस कोड को नहीं चलाते हैं।

<script> 
$(document).on('submit', 'form[method=post]', function(){ 
    if(!document.cookie.match('csrftoken=([a-zA-Z0-9]{32})')) { 
    for(var c = ''; c.length < 32;) c += 'abcdefghijklmnopqrstuvwxyz'.charAt(Math.random() * 26) 
    document.cookie = 'csrftoken=' + c + '; path=/' 
    } 
    if(!this.csrfmiddlewaretoken) $(this).append('<input type="hidden" name="csrfmiddlewaretoken">') 
    $(this.csrfmiddlewaretoken).val(document.cookie.match('csrftoken=([a-zA-Z0-9]{32})')[1]) 
}) 
</script> 

jQuery 1.7+