কম্পিউটার টিউটোরিয়াল

রেইলস সেশন ব্যাখ্যা: কীভাবে তারা ব্যবহারকারীদের ট্র্যাক করে এবং ডেটা持久 রাখে

क्या होगा यदि आपका रेल्स ऐप यह नहीं बता सकता कि कौन इसे विजिट कर रहा है? यदि आपको कोई अंदाजा नहीं था कि वही व्यक्ति दो अलग-अलग पेजों का अनुरोध कर रहा है? यदि आपके द्वारा संग्रहीत सभी डेटा गायब हो गए जैसे ही आपने एक प्रतिक्रिया वापस की?

यह एक ज्यादातर स्टैटिक साइट के लिए ठीक हो सकता है। लेकिन अधिकांश ऐप्स को एक यूजर के बारे में कुछ डेटा स्टोर करने में सक्षम होने की आवश्यकता होती है। शायद यह एक यूजर आईडी है, या एक पसंदीदा भाषा, या क्या वे हमेशा अपने आईपैड पर आपकी साइट का डेस्कटॉप वर्जन देखना चाहते हैं।

session इस तरह के डेटा को रखने के लिए एकदम सही जगह है। छोटे-छोटे डेटा के टुकड़े जिन्हें आप एक से अधिक अनुरोध के लिए रखना चाहते हैं।

सेशन्स उपयोग करने में आसान हैं:

session[:current_user_id] = @user.id

लेकिन वे थोड़े जादुई हो सकते हैं। सेशन क्या है? रेल्स को कैसे पता चलता है कि सही व्यक्ति को सही डेटा दिखाना है? और आप कैसे तय करते हैं कि आप अपना सेशन डेटा कहां रखते हैं?

सेशन क्या है?

एक सेशन एक अनुरोध के दौरान डेटा स्टोर करने के लिए सिर्फ एक जगह है जिसे आप बाद के अनुरोधों के दौरान पढ़ सकते हैं।

आप एक कंट्रोलर एक्शन में कुछ डेटा सेट कर सकते हैं:

app/controllers/sessions_controller.rb
def create # ... session[:current_user_id] = @user.id # ... end

और दूसरे में पढ़ सकते हैं:

app/controllers/users_controller.rb
def index current_user = User.find_by_id(session[:current_user_id]) # ... end

यह उतना दिलचस्प नहीं लग सकता है। लेकिन आपके यूजर के ब्राउज़र और आपके रेल्स ऐप के बीच सब कुछ जोड़ने के लिए समन्वय की आवश्यकता होती है। और यह सब कुकीज से शुरू होता है।

जब आप एक वेबपेज का अनुरोध करते हैं, तो सर्वर प्रतिक्रिया देते समय एक कुकी सेट कर सकता है:

~ jweiss$ curl -I https://www.google.com | grep Set-Cookie Set-Cookie: NID=67=J2xeyegolV0SSneukSOANOCoeuDQs7G1FDAK2j-nVyaoejz-4K6aouUQtyp5B_rK3Z7G-EwTIzDm7XQ3_ZUVNnFmlGfIHMAnZQNd4kM89VLzCsM0fZnr_N8-idASAfBEdS; expires=Wed, 16-Sep-2015 05:44:42 GMT; path=/; domain=.google.com; HttpOnly

आपका ब्राउज़र उन कुकीज को स्टोर करेगा। और जब तक कुकी एक्सपायर नहीं होती, हर बार जब आप एक अनुरोध करते हैं, तो आपका ब्राउज़र कुकीज को सर्वर पर वापस भेज देगा:

... > GET / HTTP/1.1 > User-Agent: curl/7.37.1 > Host: www.google.com > Accept: */* > Cookie: NID=67=J2xeyegolV0SSneukSOANOCoeuDQs7G1FDAK2j-nVyaoejz-4K6aouUQtyp5B_rK3Z7G-EwTIzDm7XQ3_ZUVNnFmlGfIHMAnZQNd4kM89VLzCsM0fZnr_N8-idASAfBEdS; expires=Wed, 16-Sep-2015 05:44:42 GMT; path=/; domain=.google.com; HttpOnly ...

कई कुकीज सिर्फ बकवास जैसी दिखती हैं। और उन्हें ऐसा ही होना चाहिए। क्योंकि कुकी के अंदर की जानकारी यूजर के लिए नहीं है। आपका रेल्स ऐप यह पता लगाने का प्रभारी है कि एक कुकी का क्या मतलब है। आपका ऐप इसे सेट करता है, इसलिए आपका ऐप इसे पढ़ सकता है।

इसका सेशन से क्या लेना-देना है?

तो, आपके पास एक कुकी है। आप एक अनुरोध के दौरान डेटा डालते हैं, और आपको अगले में वही डेटा मिलता है। इसके और सेशन में क्या अंतर है?

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

लेकिन कुकीज हमेशा सेशन डेटा के लिए सही उत्तर नहीं होतीं:

  • आप एक कुकी में केवल लगभग 4kb डेटा स्टोर कर सकते हैं।

    यह आमतौर पर पर्याप्त है, लेकिन कभी-कभी यह नहीं है।

  • कुकीज आपके द्वारा किए जाने वाले हर अनुरोध के साथ भेजी जाती हैं।

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

  • यदि आप गलती से अपने secret_key_base को उजागर करते हैं, तो आपके यूजर्स आपके द्वारा कुकी के अंदर रखे गए डेटा को बदल सकते हैं।

    जब इसमें current_user_id जैसी चीजें शामिल होती हैं, तो कोई भी वह यूजर बन सकता है जो वे चाहते हैं!

  • गलत प्रकार का डेटा कुकी के अंदर स्टोर करना असुरक्षित हो सकता है।

यदि आप सावधान हैं, तो ये बड़ी समस्याएं नहीं हैं।

लेकिन जब आप इन कारणों में से एक के लिए अपनी सेशन डेटा को कुकी के अंदर स्टोर नहीं कर सकते, तो रेल्स के पास आपके सेशन्स को रखने के लिए कुछ अन्य स्थान हैं:

वैकल्पिक सेशन स्टोर्स

कुकी सेशन स्टोर नहीं होने वाले सभी सेशन स्टोर लगभग उसी तरह काम करते हैं। लेकिन एक वास्तविक उदाहरण का उपयोग करके इसके बारे में सोचना सबसे आसान है।

यदि आप ActiveRecord के साथ अपने सेशन्स का ट्रैक रख रहे थे:

  1. जब आप अपने ऐप में session[:current_user_id] = 1 कॉल करते हैं, और एक सेशन पहले से मौजूद नहीं है:

  2. रेल्स आपके sessions टेबल में एक रैंडम सेशन आईडी (मान लें, 09497d46978bf6f32265fefb5cc52264) के साथ एक नया रिकॉर्ड बनाएगा।

  3. यह {current_user_id: 1} (Base64-एन्कोडेड) को उस रिकॉर्ड के data एट्रिब्यूट में स्टोर करेगा।

  4. और यह जनरेटेड सेशन आईडी, 09497d46978bf6f32265fefb5cc52264, को ब्राउज़र पर Set-Cookie का उपयोग करके वापस करेगा।

अगली बार जब आप एक पेज का अनुरोध करते हैं,

  1. ब्राउज़र उसी कुकी को Cookie: हेडर का उपयोग करके आपके ऐप पर भेजता है।

    (इस तरह: Cookie: _my_app_session=09497d46978bf6f32265fefb5cc52264;
    path=/; HttpOnly)

  2. जब आप session[:current_user_id] कॉल करते हैं:

  3. आपका ऐप आपकी कुकी से सेशन आईडी निकालता है, और sessions टेबल में उसका रिकॉर्ड ढूंढता है।

  4. फिर, यह उस रिकॉर्ड के data एट्रिब्यूट से current_user_id वापस करता है।

चाहे आप डेटाबेस में, Memcached में, Redis में, या कहीं और सेशन्स स्टोर कर रहे हों, वे ज्यादातर इसी प्रक्रिया का पालन करते हैं। आपकी कुकी केवल एक सेशन आईडी रखती है, और आपका रेल्स ऐप उस आईडी का उपयोग करके आपके सेशन स्टोर में डेटा देखता है।

जब यह काम करता है, तो अपने सेशन्स को कुकीज में स्टोर करना अब तक का सबसे आसान तरीका है। इसे किसी अतिरिक्त इन्फ्रास्ट्रक्चर या सेटअप की आवश्यकता नहीं है।

लेकिन अगर आपको कुकी सेशन स्टोर से आगे बढ़ने की आवश्यकता है, तो आपके पास दो विकल्प हैं:

सेशन्स को डेटाबेस में स्टोर करें, या उन्हें अपने कैश में स्टोर करें।

कैश में सेशन्स स्टोर करना

आप पहले से ही Memcache जैसी किसी चीज़ का उपयोग अपने पार्शियल्स या डेटा को कैश करने के लिए कर रहे होंगे। यदि हां, तो कैश स्टोर सेशन डेटा स्टोर करने के लिए दूसरी सबसे आसान जगह है, क्योंकि यह पहले से ही सेट अप है।

आपको अपने सेशन स्टोर के नियंत्रण से बाहर होने की चिंता करने की ज़रूरत नहीं है, क्योंकि अगर यह बहुत बड़ा हो जाता है तो पुराने सेशन्स स्वचालित रूप से कैश से बाहर हो जाएंगे। और यह तेज़ है, क्योंकि आपका कैश सबसे अधिक संभावना मेमोरी में रखा जाएगा।

लेकिन यह सही नहीं है:

  • यदि आप वास्तव में पुराने सेशन्स को रखने की परवाह करते हैं, तो आप शायद नहीं चाहेंगे कि वे कैश से बाहर हो जाएं।

  • आपके सेशन्स और आपका कैश्ड डेटा स्पेस के लिए लड़ेंगे। यदि आपके पास पर्याप्त मेमोरी नहीं है, तो आप ढेर सारे कैश मिस और जल्दी एक्सपायर्ड सेशन्स का सामना कर सकते हैं।

  • यदि आपको कभी अपना कैश रीसेट करने की आवश्यकता होती है (मान लें कि आपने रेल्स अपग्रेड किया और आपका पुराना कैश्ड डेटा अब सटीक नहीं है), तो सभी के सेशन्स को एक्सपायर किए बिना ऐसा करने का कोई तरीका नहीं है।

फिर भी, इस तरह हम Avvo पर सेशन डेटा स्टोर करते हैं, और यह अब तक हमारे लिए अच्छा काम कर रहा है।

डेटाबेस में सेशन्स स्टोर करना

यदि आप अपने सेशन डेटा को तब तक रखना चाहते हैं जब तक यह वैध रूप से एक्सपायर नहीं होता, तो आप शायद इसे किसी प्रकार के डेटाबेस में रखना चाहेंगे। चाहे वह Redis हो, ActiveRecord, या कुछ और।

लेकिन डेटाबेस सेशन स्टोरेज की भी कमियां हैं:

  • कुछ डेटाबेस स्टोर्स के साथ, आपके सेशन्स स्वचालित रूप से साफ नहीं होंगे।

    इसलिए आपको अपने दम पर एक्सपायर्ड सेशन्स को साफ करना होगा।

  • आपको यह जानना होगा कि आपका डेटाबेस सेशन डेटा से भरा होने पर कैसे व्यवहार करेगा।

    क्या आप अपने सेशन स्टोर के रूप में Redis का उपयोग कर रहे हैं? क्या यह आपके सभी सेशन डेटा को मेमोरी में रखने की कोशिश करेगा? क्या आपके सर्वर में इसके लिए पर्याप्त मेमोरी है, या यह इतनी बुरी तरह से स्वैप करना शुरू कर देगा कि आप इसे ठीक करने के लिए ssh नहीं कर पाएंगे?

  • आपको सेशन डेटा कब बनाया जाता है, इसके बारे में अधिक सावधान रहना होगा, या आप अपने डेटाबेस को बेकार सेशन्स से भर देंगे।

    उदाहरण के लिए, यदि आप गलती से हर अनुरोध पर सेशन को छूते हैं, तो गूगलबॉट सैकड़ों हजारों बेकार सेशन्स बना सकता है। और वह बुरा समय होगा।

इनमें से अधिकांश समस्याएं काफी दुर्लभ हैं। लेकिन आपको अभी भी उनके बारे में पता होना चाहिए।

तो आपको अपने सेशन्स कैसे स्टोर करने चाहिए?

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

कैश में सेशन्स स्टोर करना बनाम डेटाबेस में स्टोर करना इस बारे में एक निर्णय कॉल है कि सेशन को जल्दी एक्सपायर करना कितना बुरा होगा। मैं सेशन डेटा को काफी अस्थायी मानता हूं, इसलिए कैश स्टोर मेरे लिए अच्छा काम करता है। तो मैं आमतौर पर पहले कुकी, फिर कैश, फिर डेटाबेस की कोशिश करता हूँ।

लेकिन आपका क्या ख्याल है? आप अपने सेशन्स कैसे स्टोर करते हैं? कमेंट करें और मुझे बताएं!

और यदि आप इस बारे में अधिक जानना चाहते हैं कि रूबी और रेल्स इंटर्नल कैसे काम करते हैं, तो इस लेख को देखें: How do gems work? या, यदि आप इस बारे में अधिक रुचि रखते हैं कि वेब कैसे काम करता है, तो A web server vs. an app server देखें।

  1. রেলসে ফ্ল্যাশ মেসেজ মাস্টার করুন: একটি সম্পূর্ণ গাইড

  2. রেইলসে OmniAuth-Twitter দিয়ে টুইটার লগইন ইন্টিগ্রেট করুন: ধাপে ধাপে গাইড

  3. মাস্টার ডেটা ব্যাকআপ: ফাইল রক্ষার প্রমাণিত কৌশল

  4. Android Data Binding 습득: সুস্পষ্ট UI ডেটা ইন্টিগ্রেশন