Django में निष्क्रियता के कारण सत्र की समाप्ति कैसे करें?


94

हमारे Django आवेदन निम्नलिखित सत्र प्रबंधन आवश्यकताओं है।

  1. उपयोगकर्ता द्वारा ब्राउज़र बंद करने पर सत्र समाप्त हो जाता है।
  2. निष्क्रियता की अवधि के बाद सत्र समाप्त हो जाते हैं।
  3. निष्क्रियता के कारण सत्र समाप्त होने पर पता लगाएं और उपयोगकर्ता को उचित संदेश प्रदर्शित करें।
  4. निष्क्रिय सत्र की समाप्ति से कुछ मिनट पहले एक आसन्न सत्र के उपयोगकर्ताओं को चेतावनी देते हैं। चेतावनी के साथ, उपयोगकर्ताओं को अपना सत्र बढ़ाने का विकल्प प्रदान करें।
  5. यदि उपयोगकर्ता ऐप के भीतर एक लंबी व्यावसायिक गतिविधि पर काम कर रहा है जिसमें सर्वर को भेजे जाने वाले अनुरोध शामिल नहीं हैं, तो सत्र को समय समाप्त नहीं होना चाहिए।

प्रलेखन, Django कोड और इससे संबंधित कुछ ब्लॉग पोस्ट पढ़ने के बाद, मैं निम्नलिखित कार्यान्वयन दृष्टिकोण के साथ आया हूं।

आवश्यकता 1
यह आवश्यकता SESSION_EXPIRE_AT_BROWSER_CLOSE को True पर सेट करके आसानी से लागू की जाती है।

आवश्यकता 2
मैंने सत्र समाप्ति अवधि निर्धारित करने के लिए SESSION_COOKIE_AGE का उपयोग करने के लिए कुछ सिफारिशें देखी हैं। लेकिन इस विधि में निम्नलिखित समस्याएं हैं।

  • सत्र हमेशा SESSION_COOKIE_AGE के अंत में समाप्त होता है, भले ही उपयोगकर्ता सक्रिय रूप से एप्लिकेशन का उपयोग कर रहा हो। (कस्टम मिडलवेयर का उपयोग करके या प्रत्येक अनुरोध पर सत्र को सहेज कर SESSION_COOKIE_AGE को सत्र समाप्ति की समाप्ति से रोका जा सकता है। SESSION_SAVE_EVERY_REQUEST को सही करने के लिए प्रत्येक अनुरोध पर सत्र को सहेजकर रखा जा सकता है। लेकिन अगली समस्या SESSION_COOKIE_AGE के उपयोग के कारण अपरिहार्य है।)

  • कुकीज़ के काम करने के तरीके के कारण, SESSION_EXPIRE_AT_BROWSER_CLOSE और SESSION_COOKIE_AGE पारस्परिक रूप से अनन्य हैं, अर्थात कुकी या तो ब्राउज़र के करीब या निर्दिष्ट समाप्ति समय पर समाप्त हो जाती है। यदि SESSION_COOKIE_AGE का उपयोग किया जाता है और उपयोगकर्ता कुकी समाप्त होने से पहले ब्राउज़र को बंद कर देता है, तो कुकी को बरकरार रखा जाता है और ब्राउज़र को फिर से खोलना उपयोगकर्ता को (या किसी और को) सिस्टम में फिर से प्रमाणित किए बिना अनुमति देगा।

  • यदि सत्र सक्रिय है, तो यह निर्धारित करने के लिए Django केवल कुकी पर निर्भर करता है। यह सत्र समाप्ति की तारीख की जाँच नहीं करता है जो सत्र के साथ संग्रहीत है।

इस आवश्यकता को लागू करने के लिए और ऊपर बताई गई समस्याओं को हल करने के लिए निम्न विधि का उपयोग किया जा सकता है।

  • SESSION_COOKIE_AGE सेट न करें।
  • प्रत्येक अनुरोध पर सत्र की समाप्ति तिथि 'वर्तमान समय + निष्क्रियता अवधि' निर्धारित करें।
  • SessionMiddleware में ओवरराइड process_request और सत्र समाप्ति की जाँच करें। यदि यह अवधि समाप्त हो गई है तो सत्र को छोड़ दें।

आवश्यकता 3
जब हमें पता चलता है कि सत्र समाप्त हो गया है (ऊपर कस्टम सत्रलेख में), सत्र समाप्ति की ओर संकेत करने के अनुरोध पर एक विशेषता सेट करें। इस विशेषता का उपयोग उपयोगकर्ता को एक उपयुक्त संदेश प्रदर्शित करने के लिए किया जा सकता है।

आवश्यकता 4
उपयोगकर्ता निष्क्रियता का पता लगाने के लिए जावास्क्रिप्ट का उपयोग करें, चेतावनी प्रदान करें और सत्र का विस्तार करने का एक विकल्प भी। यदि उपयोगकर्ता विस्तार करना चाहता है, तो सत्र का विस्तार करने के लिए सर्वर पर एक जीवित पल्स भेजें।

आवश्यकता 5
उपयोगकर्ता गतिविधि (लंबे व्यवसाय संचालन के दौरान) का पता लगाने के लिए जावास्क्रिप्ट का उपयोग करें और सत्र को समाप्त होने से रोकने के लिए सर्वर पर जीवित दालों को भेजें।


उपरोक्त कार्यान्वयन दृष्टिकोण बहुत विस्तृत है और मैं सोच रहा था कि क्या कोई सरल विधि हो सकती है (विशेषकर आवश्यकता 2 के लिए)।

किसी भी अंतर्दृष्टि बहुत सराहना की जाएगी।


3
एक विस्तृत समाधान प्रदान करने के लिए +1
डॉन

एक मिडलवेयर है जो आपकी आवश्यकता को पूरा कर सकता है। GitHub पर और पर pypi
gbutler

1
"कुकीज़ के काम करने के तरीके के कारण, SESSION_EXPIRE_AT_BROWSER_CLOSE और SESSION_COOKIE_AGE पारस्परिक रूप से अनन्य हैं अर्थात कुकी या तो ब्राउज़र के करीब या निर्दिष्ट समय सीमा पर समाप्त हो जाती है। यदि SESSION_COOKIE_AGE का उपयोग किया जाता है और उपयोगकर्ता कुकी के समाप्त होने से पहले ब्राउज़र को बंद कर देता है।" ब्राउज़र सिस्टम में उपयोगकर्ता (या किसी और) को फिर से प्रमाणित किए बिना अनुमति देगा। " सही है अगर मैं गलत हूँ, लेकिन यह नए Django संस्करणों में अब और सच नहीं लगता है? (1.5+ कम से कम)
बॉटॉन्ड बेयर्स 12

1
"Django केवल कुकी पर निर्भर करता है जो यह निर्धारित करने के लिए मौजूद है कि क्या सत्र सक्रिय है। यह सत्र के साथ संग्रहीत सत्र समाप्ति की तारीख की जांच नहीं करता है।" यह अब सच नहीं है।
नैकपेरेक

जवाबों:


44

यहाँ एक विचार है ... SESSION_EXPIRE_AT_BROWSER_CLOSEसेटिंग के साथ ब्राउज़र पर सत्र समाप्त करें । फिर हर अनुरोध पर सत्र में टाइमस्टैम्प सेट करें।

request.session['last_activity'] = datetime.now()

और पता लगाने के लिए एक मिडिलवेयर जोड़ें कि क्या सत्र समाप्त हो गया है। कुछ इस तरह पूरी प्रक्रिया को संभालना चाहिए ...

from datetime import datetime
from django.http import HttpResponseRedirect

class SessionExpiredMiddleware:
    def process_request(request):
        last_activity = request.session['last_activity']
        now = datetime.now()

        if (now - last_activity).minutes > 10:
            # Do logout / expire session
            # and then...
            return HttpResponseRedirect("LOGIN_PAGE_URL")

        if not request.is_ajax():
            # don't set this for ajax requests or else your
            # expired session checks will keep the session from
            # expiring :)
            request.session['last_activity'] = now

फिर आपको सत्र समाप्ति के संबंध में अजाक्स कॉल के लिए प्रासंगिक डेटा वापस करने के लिए बस कुछ यूआरएल और विचार करने होंगे।

जब उपयोगकर्ता सत्र को "नवीनीकृत" करने का विरोध करता है, तो बोलने के लिए, आपको requeset.session['last_activity']केवल वर्तमान समय में फिर से सेट करना होगा

जाहिर है कि यह कोड केवल एक शुरुआत है ... लेकिन यह आपको सही रास्ते पर लाना चाहिए


मुझे यहाँ संदेह हो रहा है, लेकिन मुझे नहीं लगता कि if not request.is_ajax()यह पूरी तरह से सुरक्षित है। क्या कोई ऐसा व्यक्ति नहीं हो सकता जो सत्र की पूर्व-समाप्ति स्पूफ को पकड़ लेता है / एक अजाक्स कॉल भेज सकता है और सत्र चालू रख सकता है?
notbad.jpeg

2
@ notbad.jpeg: सामान्य रूप से "गतिविधि" आसानी से खराब हो जाती है। कोई है जो सत्र को पकड़ लेता है और अनुरोध भेजता रहता है वह सक्रिय है।
रेमकोगर्लिच

यह एक बेहतरीन जवाब है। मिडिलवेयर Django के विकास में एक बहुत ही कम आंका जाने वाला उपकरण है।
जेमी कॉन्सल

31

मैं सिर्फ Django का उपयोग करने के लिए बहुत नया हूँ।

मैं सत्र समाप्ति की तैयारी करना चाहता था यदि लॉग यूजर क्लोज्ड ब्राउजर हो या कुछ समय के लिए निष्क्रिय (निष्क्रियता के समय) में हो। जब मैंने यह पता लगाने के लिए गुगली की, तो यह एसओएफ सवाल सबसे पहले सामने आया। अच्छे उत्तर के लिए धन्यवाद, मैंने यह समझने के लिए संसाधनों को देखा कि जिंजो में अनुरोध / प्रतिक्रिया चक्र के दौरान मध्यवर्तियों कैसे काम करते हैं। यह बहुत मददगार था।

मैं यहाँ शीर्ष उत्तर के बाद अपने कोड में कस्टम मिडलवेयर लागू करने वाला था। लेकिन मुझे अभी भी कुछ संदेह नहीं था क्योंकि 2011 में यहां सबसे अच्छा जवाब संपादित किया गया था। मैंने हाल के खोज परिणाम से थोड़ा सा खोज करने में अधिक समय लिया और सरल तरीके से आया।

SESSION_EXPIRE_AT_BROWSER_CLOSE = True
SESSION_COOKIE_AGE = 10 # set just 10 seconds to test
SESSION_SAVE_EVERY_REQUEST = True

मैंने अन्य ब्राउज़रों की जाँच नहीं की, लेकिन क्रोम। 1. एक सत्र समाप्त हो गया जब मैंने SESSION_COOKIE_AGE सेट किया तो भी मैंने एक ब्राउज़र बंद कर दिया। 2. केवल जब मैं 10 सेकंड से अधिक समय के लिए निष्क्रिय था, ए सत्र समाप्त हो गया। SESSION_SAVE_EVERY_REQUEST के लिए धन्यवाद, जब भी आप नया अनुरोध करते हैं, यह सत्र समाप्त हो जाता है और समाप्ति के लिए समय-समय पर अपडेट होता है

इस डिफ़ॉल्ट व्यवहार को बदलने के लिए, SESSION_SAVE_EVERY_REQUEST सेटिंग को True पर सेट करें। ट्रू में सेट होने पर, Django हर एक अनुरोध पर सत्र को डेटाबेस में बचाएगा।

ध्यान दें कि सत्र कुकी तभी भेजी जाती है जब सत्र बनाया या संशोधित किया गया हो। यदि SESSION_SAVE_EVERY_REQUEST सही है, तो सत्र कुकी को हर अनुरोध पर भेजा जाएगा।

इसी तरह, एक सत्र कुकी के समाप्त होने वाले हिस्से को हर बार अपडेट किया जाता है, जबकि सत्र कुकी को भेजा जाता है।

django मैनुअल 1.10

मैं सिर्फ इसलिए जवाब छोड़ देता हूं कि कुछ लोग जो कि मुझ जैसे जिंजो में एक तरह के नए हैं, उन्होंने मेरे द्वारा किए गए तरीके से समाधान निकालने में ज्यादा समय नहीं लगाया।


26

django- सत्र-सुरक्षा बस यही करती है ...

... एक अतिरिक्त आवश्यकता के साथ: यदि सर्वर प्रतिक्रिया नहीं देता है या एक हमलावर ने इंटरनेट कनेक्शन काट दिया है: इसे वैसे भी समाप्त होना चाहिए।

अस्वीकरण: मैं इस एप्लिकेशन को बनाए रखता हूं। लेकिन मैं इस धागे को बहुत लंबे समय से देख रहा हूँ :)


1
शांत अनुप्रयोग - अच्छी तरह से डिजाइन और अच्छी तरह से बनाया गया है। अच्छा, साफ कोड ... धन्यवाद।
निकोरेलियस

यदि उपयोगकर्ता ब्राउज़र / टैब बंद करता है (बिना लॉग आउट किए) जब वह एस / वह निकलता है, तो क्या यह उपयोगकर्ता को लॉगआउट करने के लिए मजबूर करता है? क्या यह इस स्थिति को संभालता है?
मेहमत कागन कायाकल्प

यह शुद्ध-http सत्र कुकी एक्सपायरी द्वारा संभाला जाएगा यह नहीं होगा?
jpic

10

अपनी दूसरी आवश्यकता को पूरा करने का एक आसान तरीका यह होगा कि आप सेटिंग में सेकंड में उपयुक्त राशि में SESSION_COOKIE_AGE मान सेट करें। उदाहरण के लिए:

SESSION_COOKIE_AGE = 600      #10 minutes.

हालाँकि, केवल यह करने से सत्र 10 मिनट के बाद समाप्त हो जाएगा कि उपयोगकर्ता कुछ गतिविधि प्रदर्शित करता है या नहीं। इस समस्या से निपटने के लिए, समाप्ति समय को स्वचालित रूप से (एक और 10 मिनट के लिए) नवीनीकृत किया जा सकता है, हर बार उपयोगकर्ता निम्नलिखित वाक्य के साथ किसी भी प्रकार का अनुरोध करता है:

request.session.set_expiry(request.session.get_expiry_age())

2
SESSION_COOKIE_AGE = 600 यह हर नए पेज के अनुरोध या पेज रिफ्रेश के साथ सत्र की आयु
बढ़ाएगा

1
मैं पुष्टि करता हूं कि बस सेटिंग SESSION_COOKIE_AGEपर्याप्त है और कोई भी अनुरोध (सत्र कुकी भेजना) स्वचालित रूप से सत्र कुकी समाप्ति को ताज़ा कर देगा।
ब्रूनो डेथिलियर्स

3

इसके अलावा, आप कार्यों में स्टैकओवरफ़्लो बिल्ड का उपयोग कर सकते हैं

SESSION_SAVE_EVERY_REQUEST = True

पूरी तरह से असंबंधित - यह सत्र को संशोधित किए बिना प्रत्येक अनुरोध पर सत्र बचाने ("सत्र कुकी ताज़ा नहीं") के लिए है।
ब्रूनो डेथिलियर्स

3

पहले अनुरोध में, आप सत्र समाप्ति की समय सीमा निर्धारित कर सकते हैं

self.request.session['access_key'] = access_key
self.request.session['access_token'] = access_token
self.request.session.set_expiry(set_age) #in seconds 

और access_key और token का उपयोग करते समय,

try:
    key = self.request.session['access_key']
except KeyError:
    age = self.request.session.get_expiry_age()
    if age > set_age:
        #redirect to login page
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.