2012-03-14 13 views
9

इस Django दृश्य जो वर्तमान उपयोगकर्ता के लिए जुड़े मदों की एक सूची मिल जाएगा पर विचार करें:AJAX अनुरोधों में सत्र टाइमआउट को संभालने का सबसे अच्छा तरीका क्या है?

@login_required 
def list_items(request, page_number=0): 
    items = Paginator(request.user.items, 5).page(page_number).object_list 
    return HttpResponse(cjson.encode(items)) 

जाहिर है, इसके लिए दृश्य की पहुंच को प्रतिबंधित करने, login_required डेकोरेटर का उपयोग करना चाहता लॉग-इन उपयोगकर्ताओं।

login_required क्या करता है जब कोई गैर-प्रमाणीकृत उपयोगकर्ता दृश्य तक पहुंचने का प्रयास करता है? यह HttpResponseRedirectsettings.LOGIN_URL पर लौटाता है।

var getPage = function(pageNumber) { 
    $.ajax({ 
     url: "/list_items/" + pageNumber + "/", 
     success: function(data) { 
      $("#list_container").html(formatData(data)) 
     } 
    }); 
}; 

मान लीजिए settings.SESSION_COOKIE_AGE = 60 सेकंड:

इस जावा स्क्रिप्ट कोड है, जो दृश्य कॉल पर विचार करें।

एक उपयोगकर्ता पेज 1 करने के लिए चला जाता है, 61 सेकंड के लिए इसे पढ़ता है तो पेज 2 के लिए बटन पर क्लिक करता है, Django के login_required डेकोरेटर की पहचान करेगा कि सत्र अब सक्रिय नहीं है, और एक HttpResponseRedirect(settings.LOGIN_URL) वापस आ जाएगी, जो कारण होगा JSON-encoded सूची के बजाय एक HTML लॉगिन पृष्ठ प्राप्त करने के लिए success कॉलबैक।

This is where it happens.
It's called by user_passes_test here.

सबसे अच्छा तरीका यह संभाल करने के लिए क्या है?

यहाँ कुछ चीजें मैं के बारे में सोचा है या नहीं:

1.success कॉलबैक प्रतिक्रिया की जाँच करनी चाहिए, और अगर यह जो कुछ भी साधन (जाँच करता है, तो सामग्री प्रकार एचटीएमएल है, सामग्री की जाँच से एक प्रवेश पृष्ठ, हो जाता है को देखने के , आदि)। लेकिन इसका मतलब यह है कि हम सभी AJAX तो जैसे एक कॉलबैक आवरण के साथ कॉल रैप करने के लिए है:

$.ajax({ 
     url: "/list_items/" + pageNumber + "/", 
     success: sessionExpiryCallbackWrapper(function(data) { 
      $("#list_container").html(formatData(data)) 
     }) 
    }); 

लेकिन यह बदसूरत है, और डेवलपर्स के इस हर जगह करना भूल भी सकते हैं।

2. सभी अनुरोधों को संभालने के लिए $.ajaxComplete का उपयोग करें।

successCallback(); // success is called before complete 
    completeCallback(); 
    globalCompleteCallback(); // this is called after the local callback 

तो हम केवल रीडायरेक्ट, अमान्य डेटा इसे प्राप्त की वजह से पकड़ने के बाद successCallback में नाकाम रही है, और जे एस त्रुटियों के साथ संभवतः:

$.ajaxComplete(globalCompleteCallback); 
    $.ajax({ 
     success: successCallback, 
     complete: completeCallback 
    }); 

लेकिन यह कॉल आदेश है।

3. तो login_required AJAX अनुरोध पर 403 वापसी होगी:

if not user.is_authenticated(): 
     if request.is_ajax(): 
      # send 403 to ajax calls 
      return HttpResponse403("you are not logged in") 
     else: 
      # regular code path 
      return HttpResponseRedirect(settings.LOGIN_URL) 

लेकिन login_required सिर्फ user_passes_test जो ऐसा नहीं करता है का उपयोग करता है।

user_passes_test में वहां बहुत सारी कार्यक्षमता है, इसलिए इसे पुन: कार्यान्वित करना इतना अच्छा विचार नहीं है।

AJAX कॉल के लिए टाइमआउट को संभालने का सबसे अच्छा तरीका क्या है?

+1

क्षमा करें, लेकिन मैं आप पर सभी दार्शनिक जा रहा हूं। सत्र टाइमआउट का मूल उद्देश्य सर्वर को महत्वपूर्ण संसाधन रखने या प्रत्येक अनुरोध पर महंगे संचालन करने से रोकने के लिए था। अब हमारे पास अधिकांश काम करने वाले क्लाइंट-साइड फ्रेमवर्क हैं। तो शॉर्ट सत्र टाइमआउट को भी क्यों जरूरी है? –

+0

@ डेवमेथविन सत्र टाइमआउट को सत्र अपहरण के लिए खिड़की को संकुचित करने के लिए आवश्यक है ए) तार/वायु या बी पर) शारीरिक रूप से किसी और के कंप्यूटर पर जाने के बाद शारीरिक रूप से एएफके चला गया है। – Prody

+1

हालांकि यह समस्या हल करने में बहुत आसान लगती है, बस क्लाइंट सत्र टाइमआउट सर्वर से कम हो। यदि ऐसा है तो क्लाइंट के लिए यह अनुरोध करना हमेशा दुर्लभ होना चाहिए कि एक वैध सत्र के बिना सर्वर पर खुद को पाता है। इसके अलावा इसका मतलब है कि आप एक अच्छा दिखने वाले क्लाइंट-आरंभ किए गए "आपके सत्र का समय समाप्त हो गया है" संदेश डाल सकते हैं। –

उत्तर

5

मैं अपने सत्र टाइमआउट विधि को जांचकर इसे संभाल दूंगा कि यह AJAX के साथ अनुरोध किया जा रहा है या नहीं। यदि यह AJAX है, तो एक खाली जेसन स्ट्रिंग के साथ 401 अधिकृत नहीं है (या 403 वर्जित या जो भी स्थिति समझ में आता है) स्थिति कोड। इसके बाद, अपने जावास्क्रिप्ट में, एक वैश्विक ajaxError हैंडलर बांधें जो उस स्थिति कोड की जांच करता है और इसे उचित तरीके से संभालता है।

+1

यह वही है जो मैंने अंततः किया था, लेकिन मुझे अनुरोध है कि अगर किसी भी तरह से रीडायरेक्ट करने के बजाय request.is_ajax() अन्यथा रीडायरेक्ट टोलॉगिन पेज() 'को वापस करने के लिए मुझे एक नया 'login_required' सजावट' वापस भेजना है। – Prody

0

आप http://amplifyjs.com/ की तरह कुछ आप अपनी AJAX कॉल के लिए एक अच्छा आवरण लिखना और फिर अगर उपयोगकर्ता अभी भी AJAX कॉल करने से पहले में लॉग ऑन है की जाँच करने के लिए अपने data mapping सुविधा का उपयोग करने देता है कि इस्तेमाल कर सकते हैं।

इस तरह से आप एक क्लाइंट-साइड टाइमर हो सकते हैं जो उपयोगकर्ता को लॉग-आउट स्थिति में सेट करता है और एक संकेत प्रदान करता है ताकि प्रत्येक AJAX कॉल से पहले लॉगिन चेक करने की आवश्यकता न हो।

वैकल्पिक रूप से आप एक कस्टम decoder का उपयोग कर सकते हैं जो उपयोगकर्ता को लॉग इन करने और उपयोगकर्ता लॉग आउट होने पर AJAX कॉल को फिर से प्रयास करने के लिए कहता है। इसे सभी एक्सएचआर डेटा और कॉलबैक को स्टोर करने की आवश्यकता होगी जब तक उपयोगकर्ता लॉग इन नहीं करता है।

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

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