जब वे अपने कंप्यूटर को सोने के लिए डालते हैं, तो एक वेबसाइट से किसी उपयोगकर्ता को लॉग इन करें


11

यह एक विचित्र है। हमारे पास एक Laravel वेबसाइट है, और उक्त साइट पर हमारे पास प्रति उपयोगकर्ता एक टाइमर है, जहां उन्हें बूट होने से पहले निष्क्रिय होने के 15 मिनट मिलते हैं।

हम इसे एक टाइमर के माध्यम से करते हैं जो एक प्रतिक्रिया घटक में पृष्ठ पर बैठता है, यह काम करता है जैसा हम चाहते हैं, लेकिन अब हमारे पास एक नया मुद्दा है: यदि कोई उपयोगकर्ता लॉग इन है और अपने लैपटॉप के ढक्कन को बंद कर देता है तो वेबसाइट को उन्हें बूट करना चाहिए । बैंक ऐसा करते हैं, स्कूल और विश्वविद्यालय ऐसा करते हैं, सरकारी साइटें भी ऐसा करती हैं। तो यह संभव है, बस यह सुनिश्चित नहीं है कि कैसे।

हम लार्वा-वेबसोकेट्स लाइब्रेरी और इको का उपयोग करके वेब सॉकेट का उपयोग करते हैं । मैं ऐसा होता देखना चाहता हूं:

  • एक बार जब आप अपना लैपटॉप बूट बंद करते हैं तो आप लॉगिन स्क्रीन पर पहुंच जाते हैं। तो अगली बार जब आप लैपटॉप खोलते हैं और लॉगिन करते हैं, और उस ब्राउज़र को देखें जिसे आप लॉगिन स्क्रीन पर हैं। यह जल्दी से नहीं होता है, लेकिन हमें मूल रूप से पृष्ठ को ताज़ा करने के लिए कहकर सामने वाले को कुछ भेजने की ज़रूरत होती है, एक बार सत्र समाप्त हो जाने पर, हम सत्र को 15 मिनट के लार्वा पर सेट करते हैं।

कुछ लोगों ने अन्य समान प्रश्नों में सुझाव दिया है:

  • एक कस्टम वेब-सॉकेट हैंडलर बनाने के लिए
  • बैक एंड पर यूजर कुकी के साथ सेशन कुकी (ब्राउज़र में) की तुलना करना।
  • सामने के छोर पर एक टाइमर चल रहा है (हम करते हैं, यह तब बंद हो जाता है जब आप लैपटॉप का ढक्कन बंद करते हैं)

सबसे लोकप्रिय एक वेब-सॉकेट का उपयोग करना प्रतीत होता है, जो उपयोगकर्ता को डिस्कनेक्ट करने के लिए सुनता है और फिर उन्हें बूट करता है, जो ठीक है और सभी है, लेकिन फिर आप एक ब्राउज़र को एक अनुरोध कैसे भेज सकते हैं जो तब बूट करने के लिए निलंबित है?

मुझे requestIdleCallback () मिला है , लेकिन फिर से, मुझे नहीं लगता कि यह वही है जो मैं चाहता हूं अगर मेरे पास साइट पर पहले से ही एक दिल की धड़कन का टाइमर है। यह सभी ब्राउज़रों में भी काम नहीं करता है।

मैं इसे पूरा करने के बारे में यहां बहुत कुछ खो रहा हूं, उदाहरण मैं दे सकता हूं:

अपने बैंक में लॉग इन करें, अपने कंप्यूटर को सोने के लिए रखें, 15-20 मिनट प्रतीक्षा करें, कंप्यूटर को जागृत करें, लॉग इन करें और देखें कि आपका बैंक अब लॉगिन स्क्रीन पर है। यही तो मैं चाहता हूं । लेकिन मुझे नहीं पता कि इसे कैसे पूरा किया जाए।

आप पिछले छोर से एक "स्लीपिंग" ब्राउज़र में ईवेंट भेज सकते हैं, और हाँ, यह बैक एंड सॉल्यूशन होना चाहिए, फिर आप फ्रंट एंड को कैसे अपडेट करते हैं, ताकि वे लैपटॉप को पढ़ते समय लॉगआउट स्क्रीन पर हों या कंप्यूटर?


7
बस सत्र कुकी समाप्ति की तिथि "अब + 15 मिनट" पर सेट करें ... हालाँकि आप अभी भी अंतिम स्क्रीन देख सकते हैं, अगर कुकी समाप्त हो गई है, तो आप उस सत्र में कार्य नहीं कर सकते। और "बूट टू लॉग स्क्रीन" - मुझे पूरा यकीन है कि एक ओएस सेटिंग है जो निष्क्रियता के एक निश्चित समय के बाद स्वचालित रूप से एक कंप्यूटर को लॉगआउट करेगी ..
लार्स स्टेग्लिट्ज़

1
जब भी कोई साइट लोड होती है, तो आप एक जावास्क्रिप्ट टाइमर init कर सकते हैं, आपके सत्र कुकी के समान टाइमआउट के साथ ... यदि टाइमर "रिंग" होता है, तो उपयोगकर्ता इतने लंबे समय तक निष्क्रिय था। फिर आप उसे लॉग आउट करेंगे (AJAX कॉल) और ब्राउज़र को लॉगिन-स्क्रीन या "क्षमा करें, हमने निष्क्रियता के कारण आपको लॉग आउट किया है" स्क्रीन;)
लार्स स्टेग्लिट्ज़

1
ठीक है मैंने किया है मैं अभी उत्तर जोड़ रहा हूं।
दत्तो डीटी

1
तो क्या यह उपयोगी था?
दत्तो डीटी

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

जवाबों:


0

अपडेट करें

WebSocket अनुरोध के बारे में, मैं आप उपयोग कर रहे मान Laravel WebSockets के साथ pusherPusher.io टाइमआउट का समर्थन नहीं करता है , आप इस समर्थन लेख को पढ़ सकते हैं "क्या आप चैनल पुशर्स-जेएस क्लाइंट लाइब्रेरी में कनेक्शन टाइमआउट सुविधा जोड़ने की योजना बना रहे हैं?" । यदि आप लारवेल डीबग मोड ( APP_DEBUG=true अंदर .env ) और बेगिन laravel-websocketsको टर्मिनल ( php artisan websockets:serve) से सक्षम करते हैं तो आप इसका परीक्षण कर सकते हैं ताकि आप आउटपुट लॉग ईवेंट देख सकें। यदि आप लैपटॉप के ढक्कन को बंद करने या कंप्यूटर को हाइबरनेशन मोड ( स्लीप ) पर सेट करने का प्रयास करते हैं , तो आपको इस ईवेंट के बारे में कोई संदेश दिखाई नहीं देगा। आप इसे pusherप्रोटोकॉल के साथ नहीं कर सकते । वहाँ उपस्थिति घटना हैmember_removed , लेकिन यह तब होता है जब आप टैब बंद करते हैं या आप लॉगआउट करते हैं। बेशक आप अपने क्लाइंट कस्टम इवेंट को उपस्थिति चैनल पर ट्रिगर कर सकते हैं, लेकिन यह करने के लिए कि आपको क्लाइंट साइड में टाइमर सेटअप की आवश्यकता है और आपको laravel-websocketsसर्वर के लिए एक सर्विस प्रोवाइडर बनाना होगा जैसे कि इस github इश्यू "के लिए एक तरीका मौजूद है" वेबहुक लागू करें? "

कुछ लोगों ने अन्य समान प्रश्नों में सुझाव दिया है:

...

  • सामने के छोर पर एक टाइमर चल रहा है ( हम करते हैं, यह तब बंद हो जाता है जब आप लैपटॉप का ढक्कन बंद करते हैं )

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

क्लाइंट में समय तर्क को लागू करना

आप इस कार्यान्वयन को इस संबंधित Q / A पर भी देख सकते हैं : क्या कोई डेस्कटॉप ब्राउज़र यह पता लगा सकता है कि कंप्यूटर नींद से कब शुरू होता है?

आप प्रत्येक मिनट को चलाने के लिए क्लाइंट में टाइमर सेट कर सकते हैं। हम टाइमर अंतराल पर भरोसा नहीं करेंगे , लेकिन इसके बजाय कि टाइमर एक बाहरी गुंजाइश तिथि चर की जांच करेगा यदि अंतिम टाइमर के बाद से समय अवधि 15मिनट से अधिक है ; यदि यह है, तो इसका मतलब है कि ब्राउज़र / जेएस ने किसी कारण से निष्पादन रोक दिया है , संभवतः डिवाइस ( नींद ) का हाइबरनेशन और फिर आप उपयोगकर्ता को लॉगआउट मार्ग पर पुनर्निर्देशित करते हैं।

उदाहरण JS क्लाइंट कोड:

// Set a variable to check previous time
let clientSession = new Date;

// Setup the client session checking timer
let clientSessionTimer = setInterval(() => {
  const now = new Date;
  // Get how many seconds have passed since last check
  const secondsSpan = (now - clientSession) / 1000;

  // If the 1 minute timer has exceeded 15 minutes trigger logout and clear timer
  if (secondsSpan > (60 * 15)) {
    // For some reason JS halted execution, so we'll proceed with logging out
    clearInterval(clientSessionTimer);
    window.location.href = '/logout/session'
  } else {
    // The timer runs as it should, update the clientSession time
    clientSession = now;
  }

}, 1000 * 60);

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

वेब वर्कर्स उदाहरण

आप वेब वर्कर्स API का उपयोग किसी वेब वर्कर को ज्यादा सुरक्षित करने के लिए कर सकते हैं:

पृष्ठ जेएस कोड:

const logoutWorker = new Worker('logoutWorker.js');
logoutWorker.onmessage = function (ev) {

  if (ev && ev.data === 'wakeup') {
    logoutWorker.terminate();
    // window.location.href = '/logout/session'
  } else {
    // The timer runs as it should, nothing to do
  }
}

वेब कार्यकर्ता logoutWorker.jsकोड:

let clientSession = new Date();

let clientSessionTimer = setInterval(() => {
  const now = new Date;
  const secondsSpan = (now - clientSession) / 1000;

  if (secondsSpan > 15) {
    postMessage('wakeup'); // Send a message wakeup to the worker page
    clearInterval(clientSessionTimer); // Clear the timer
  } else {
    clientSession = now; // Update the clientSession timer variable
    postMessage('update'); // And post a message to the page ONLY IF needed
  }
}, 1000);

आप यहां उसी 15सेकंड टाइमर के साथ वेब वर्कर उदाहरण भी देख सकते हैं


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

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

कृपया नमूना उदाहरणों को अपडेट करें जो अभी भी काम नहीं करते हैं। कोई बात नहीं 15 सेकंड के बाद पहली बार आपको लॉग आउट करता है। दूसरा कभी भी आपको लॉग आउट नहीं करता है।
इस्लाम एल्शोबोक्शी

@IslamElshobokshy मैंने इसे जरूर अपडेट किया है। इससे पहले कि यह एक मुद्दा था, और अब यह उम्मीद के मुताबिक काम करता है। कृपया पृष्ठ को वापस लाएं यदि आपने ?v=1अंत तक एक परम को जोड़ा या नहीं ।
क्रिस्टोस लिट्रास

1
ग्रेट सॉल्यूशन + 3
अमेरिक्लिसा

0

सबसे पहले, आइए इस पर विस्तार करें कि बैंकिंग वेबसाइटें बिना गतिविधि के 15 मिनट बाद आपको लॉग आउट क्यों करती हैं। यह सुरक्षा के लिए पीसीआई की आवश्यकता है।

PCI-DSS की आवश्यकता 8.1.8 :

8.1.8 यदि कोई सत्र 15 मिनट से अधिक समय के लिए निष्क्रिय रहा है, तो टर्मिनल या सत्र को फिर से सक्रिय करने के लिए उपयोगकर्ता को पुन: प्रमाणित करने की आवश्यकता होती है।

इस समाधान को प्राप्त करने के लिए वास्तव में आप इसे होने की कल्पना से कहीं अधिक आदिम हैं। इसके लिए न तो वेबसोकेट के उपयोग की आवश्यकता होती है और न ही ग्राहक की मशीन की स्थिति के बारे में कुछ जानना (नींद या जागना या अन्यथा)। उस सत्र का उपयोग करके वर्तमान अनुरोध के बीच के समय को जानना आवश्यक है और उसी सत्र का उपयोग करके अंतिम अनुरोध और यह सुनिश्चित करना कि वे 15 मिनट से अधिक नहीं हैं। यदि वे उपयोगकर्ता हैं तो फिर से प्रमाणित किया जाना है। यदि वे नहीं हैं तो आप अनुरोध के साथ आगे बढ़ सकते हैं।

"सत्र समय समाप्त" संदेश

आप शायद सोच रहे हैं (यदि यह इतना आसान है) जब आप कंप्यूटर को सोने और उसे जगाने के लिए सत्र लगाते हैं तो संदेश कैसे प्रकट होता है। यह हिस्सा भ्रामक रूप से सरल है।

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

हालाँकि, यह जावास्क्रिप्ट मैसेज मोडल (यदि आप जिसका जिक्र कर रहे हैं) के लिए कुछ बैंकिंग वेबसाइटें ऐसा नहीं करेंगी। यह भी नहीं सभी ब्राउज़र सभी परिदृश्यों में पृष्ठ पर एक कठिन ताज़ा करते हैं। तो एक और दृष्टिकोण लिया जा सकता है। इसके बजाय ब्राउज़र में एक टाइमर है जो 15 मिनट के बाद बाहर निकलता है, आप केवल एक लोडिंग टाइम को जावास्क्रिप्ट के रूप में जावास्क्रिप्ट में पृष्ठ लोड कर सकते हैं और 1 सेकंड का अंतराल समय निकाल सकते हैं जो उस टाइमस्टैम्प की तुलना कंप्यूटर के वर्तमान टाइमस्टैम्प से करता है। यदि वे 15 मिनट से अधिक अलग हैं, तो सत्र समाप्त कर दिया जाना चाहिए।

window.onload = function() {

    sessionStart = Date.now();
    timer = setInterval(function() {
        if (Date.now() - sessionStart > 15 * 60 * 1000) {
            clearTimeout(timer);
            alert("Session Timed out!");
            window.location = "http://www.example.com/login";
        }
    }, 1000);


};

यहां तक ​​कि अगर कंप्यूटर सो जाता है और टाइमर बंद हो जाता है, तो सत्र अंततः सर्वर की ओर से समय समाप्त हो जाएगा ( विवरण के लिए नीचे अनुभाग देखें ) और जब कंप्यूटर फिर से जागता है तो 1 सेकंड के अंतराल के साथ टाइमर अंततः स्टार्टअप को फिर से शुरू करेगा। संदेश (जैसे कि उपयोगकर्ता समय से सो रहा था जब कंप्यूटर सो रहा था)। कंप्यूटर के सो जाने के समय के बीच का समय और कंप्यूटर के जागने का समय कोई फर्क नहीं पड़ता क्योंकि टाइमस्टैम्प स्मृति में रहेगा। क्लाइंट और सर्वर के बीच डिस्कनेक्ट महत्वहीन है, क्योंकि उन्हें सत्र के लिए सर्वर साइड पर ठीक से समाप्त होने के लिए इस जानकारी को संवाद करने की आवश्यकता नहीं है। सर्वर अपना कचरा संग्रह कर सकता है और ग्राहक से संचार के बिना सत्र को समाप्त कर सकता है (अर्थात अतुल्यकालिक रूप से )।

मानो या न मानो बैंकों को ग्राहक के अंदर की गतिविधि की परवाह नहीं है। वे केवल सर्वर से अनुरोध गतिविधि के बारे में परवाह करते हैं। इसलिए यदि आप सोच रहे हैं कि जब उपयोगकर्ता उसी पेज पर 15 मिनट से अधिक समय तक सत्र को जीवित रखते हैं, तो वे उपयोगकर्ता से पूछने के बाद सत्र को ताज़ा करने के लिए पृष्ठभूमि में AJAX अनुरोध भेजते हैं। जारी रखना चाहते हैं।

यह उसी onloadघटना कॉलबैक में किया जा सकता है जिसे हमने पहले इस्तेमाल किया था:

window.onload = function() {

    sessionStart = Date.now();
    timer = setInterval(function() {
        if (Date.now() - sessionStart > 10 * 60 * 1000) {
           if (confirm("Your session is about to timeout. Do you wish to continue?")) {
                // send ajax request to refresh session TTL here
                // reset the timer
                sessionStart = Date.now();
            }
        } else if (Date.now() - sessionStart > 15 * 60 * 1000) {
            clearTimeout(timer);
            alert("Session Timed out!");
            window.location = "http://www.example.com/login";
        }
    }, 1000);


};

सर्वर की ओर से सत्र समाप्ति को संभालना

सर्वर की ओर से सत्र समाप्ति को संभालने के लिए कई दृष्टिकोण हैं। इस पर निर्भर करता है कि आप किसका उपयोग करते हैं, आपको अलग-अलग रणनीति की आवश्यकता होगी। एक PHP के डिफ़ॉल्ट सत्र हैंडलर का उपयोग कर रहा है और इसे session.max_lifetime15 मिनट के बाद समाप्त करने के लिए सेट कर रहा है (यह सत्र डेटा को पूरी तरह से सर्वर की तरफ हटाता है और इस प्रकार क्लाइंट की कुकी को अमान्य कर देता है)।

यदि आप डिफ़ॉल्ट सत्र हैंडलर तंत्र को ऐसा करने देते हैं, तो आप उन मुद्दों पर चल सकते हैं, जिनके आधार पर हैंडलर का उपयोग किया जाता है (फ़ाइलें, मेमकाटेड, रेडिस, कस्टम, आदि)।

फ़ाइलों (डिफ़ॉल्ट हैंडलर) के साथ कचरा संग्रह दो तरीकों में से एक में होता है:

  • अधिकांश डेबियन आधारित प्रणालियां एक क्रॉन जॉब के माध्यम से अपनी स्वयं की जीसी करती हैं (जो आपके परिदृश्य के लिए बहुत अच्छा काम करती है)
  • अन्य डिस्ट्रोस PHP के डिफ़ॉल्ट जीसी तंत्र को संभालते हैं, जो PHP के लिए आने वाले प्रत्येक अनुरोध से एक संभाव्य परिणाम पर आधारित होता है जो फ़ाइल मैम की सत्र फ़ाइलों की जाँच करता है और उन पिछले को हटा देता है session.max_lifetime। इस दृष्टिकोण के साथ समस्या यह है कि कम ट्रैफ़िक साइटों पर एक सत्र संभावित रूप से सर्वर पर लंबे समय तक बैठ सकता है जब तक session.gc_probabilityकि सत्र फ़ाइलों को साफ करने के लिए जीसी को आमंत्रित करने के लिए पर्याप्त स्कोर ( स्कोर के आधार पर ) नहीं आते हैं ।

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

एक कस्टम सत्र हैंडलर के साथ आपको अपना स्वयं का जीसी तंत्र बनाना होगा। के माध्यम से SessionHandlerInterfaceआप एक को लागू होता gcविधि है कि हाथ आप सत्र का अधिकतम जीवनकाल अंतराल और आपके द्वारा सत्यापित करता है, तो सत्र इस अंतराल के आधार पर अपने जीवनकाल बीत चुका है के लिए जिम्मेदार हो सकता है और वहाँ से अपने कचरा संग्रहण करना चाहते हैं।

आप एक अलग अंतिम बिंदु भी सेट कर सकते हैं जो सत्र टीटीएल (ग्राहक पक्ष पर अतुल्यकालिक AJAX अनुरोध के माध्यम से) की जांच करता है और यदि सत्र समाप्त हो गया है (तो उपयोगकर्ता को फिर से प्रमाणित करने के लिए जावास्क्रिप्ट को मजबूर करके) एक प्रतिक्रिया भेजता है।


0

तो आइडिया सेट इन्टरवल और सॉकेट्स के पीछे है, सेटइंटरवल को ज्यादातर ब्राउज़र में सपोर्ट किया जाता है और जावास्क्रिप्ट WbsocketApi को लगभग हर ब्रोसर में सपोर्ट किया जाता है।

संक्षिप्त अवलोकन: setInterval () - यह फ़ंक्शन व्यवहार तब होता है जब आपका कंप्यूटर नींद / निलंबित / हाइबरनेट मोड पर होता है और इसे रोका जाता है और जब आप जागृत मोड पर होते हैं तो यह स्वयं को फिर से शुरू करता है।

निम्नलिखित कोड निम्न पर, पहले (शायद एक ही समय पर) करता है, लेकिन यह कनेक्शनों को सुनने के लिए php server_socket शुरू करता है,

जावास्क्रिप्ट से वेबसोकेट एपि हर 2 सेकंड में यूनिक्स टाइमस्टैम्प मिलीसेकंड में वर्तमान टाइमस्टैम्प भेजता है आपके पास 1 सेकंड हो सकता है यह आपके ऊपर है।

उसके बाद php सर्वर सॉकेट इस समय हो रहा है और जाँच करता है कि क्या इसकी तुलना करने के लिए पिछली बार की तरह कुछ भी है, जब कोड पहली त्वरित है php के पास पिछले समय की तरह कुछ भी नहीं है जो इसे उस समय की तुलना करने के लिए है जिसे जावास्क्रिप्ट वेबसैट से भेजा गया था, इसलिए php कुछ भी नहीं करता है लेकिन इस समय को 'prev_time' नामक सत्र में बचाता है और जावास्क्रिप्ट सॉकेट से दूसरी बार डेटा प्राप्त होने की प्रतीक्षा करता है, इसलिए यहां दूसरा चक्र शुरू होता है। जब javascript WebsocketApi से php सर्वर सॉकेट नए समय के डेटा की जाँच करता है, तो यह इस नए प्राप्त समय डेटा की तुलना करने के लिए पिछली बार की तरह कुछ भी होता है, इसका मतलब है कि अगर php चेक अगर 'prev_time' नामक सत्र मौजूद है, जैसा कि हम दूसरे चक्र php में हैं। यह मौजूद है, यह इसका मूल्य है और निम्नलिखित करता है$diff = $new_time - $prev_time, $ अंतर 2 सेकंड या 2000 मिलिसेकंड होगा क्योंकि याद रखें कि हमारा सेटइंटरवल चक्र हर 2 सेकंड और समय प्रारूप में होता है जो हम भेज रहे हैं।

if($diff<3000)अगर यह पता है कि उपयोगकर्ता सक्रिय है, तो फ़र्क 3000 से कम होने पर php जाँचता है, फिर से आप चाहें तो इस सेकंड में फेरबदल कर सकते हैं, मैं 3000 चुनता हूँ क्योंकि नेटवर्क में संभावित विलंबता लगभग असंभव है लेकिन आप जानते हैं कि मैं हमेशा सतर्क रहता हूँ जब यह नेटवर्क पर आता है, तो चलिए जारी रखते हैं, जब php निर्धारित करता है कि उपयोगकर्ता सक्रिय है php बस रीसेट करता है 'prev_time' सत्र जिसके मूल्य $new_timeको नव प्राप्त किया गया था और सिर्फ परीक्षण प्रयोजनों के लिए यह संदेश को वापस भेजता है जावास्क्रिप्ट सॉकेट,

लेकिन अगर $diffयह 3000 से अधिक है, तो इसका मतलब है कि किसी चीज ने हमारे सेट को बाधित कर दिया है और केवल एक ही रास्ता है और ऐसा हो सकता है और मुझे लगता है कि आप पहले से ही जानते हैं कि मैं क्या कह रहा हूं, इसलिए else( if($diff<3000)) के तर्क में आप विशिष्ट सत्र को नष्ट करके उपयोगकर्ता को लॉगआउट कर सकते हैं और यदि आप पुनर्निर्देशित करना चाहते हैं आप कुछ पाठ को javacript सॉकेट में भेज सकते हैं और एक तर्क बना सकते हैं जो window.location = "/login"पाठ के आधार पर निष्पादित करेगा , यही है यहां कोड है:

पहले यह जावास्क्रिप्ट को लोड करने के लिए index.html फ़ाइल है:

<html>
    <body>
        <div id="printer"></div>
        <script src="javascript_client_socket.js"></script>
    </body>
</html>

तो यह जावास्क्रिप्ट है यह वास्तव में खूबसूरती से कोडित नहीं है, लेकिन आप पढ़ सकते हैं टिप्पणी टिप्पणियाँ वे महत्वपूर्ण हैं:

var socket = new WebSocket('ws://localhost:34237'); // connecting to socket
    // Open the socket
socket.onopen = function(event) { // detecting when connection is established
        setInterval(function(){ //seting interval for 2 seconds
            var date = new Date(); //grabing current date
            var nowtime = Date.parse(date); // parisng it in miliseconds
            var msg = 'I am the client.'; //jsut testing message


            // Send an initial message
            socket.send(nowtime); //sending the time to php socket
    },2000);

};


// Listen for messages
socket.onmessage = function(event) { //print text which will be sent by php socket 
    console.log('php: ' + event.data);
};

// Listen for socket closes
socket.onclose = function(event) {
    console.log('Client notified socket has closed', event);
};

अब यहाँ php कोड का एक हिस्सा है, चिंता न करें कि पूर्ण कोड भी है, लेकिन यह हिस्सा वास्तव में ऊपर बताई गई नौकरियों से है जो आपको अन्य कार्यों से भी मिलेंगे, लेकिन वे डिकोडिंग और जावास्क्रिप्ट सॉकेट्स के साथ काम करने के लिए हैं, इसलिए यह वास्तविक चीज़ सही है यहाँ पढ़ें टिप्पणियाँ वे महत्वपूर्ण हैं:

<?php 
            $decoded_data = unmask($data /* $data is actual data received from javascript socket */); //grabbing data and unmasking it | unmasking is for javascript sockets don't mind this
            print("< ".$decoded_data."\n");
            $response = strrev($decoded_data);
            $jsTime = (int) $decoded_data; /* time sent by javascript in MILISECONDS IN UNIX FORMAT  */
            if (isset($_SESSION['prev_time'])) { /** check if we have stored previous time in the session */
               $prev_time = (int) $_SESSION['prev_time']; /** grabbing the previous time from session */
               $diff = $jsTime-$prev_time; /** getting the difference newly sent time and previous time by subtracting */
               print("$jsTime - $prev_time = $diff"); /** printing the difference */
               if($diff<3000){ /** checking if difference is less than 3 second if it is it means pc was not at sleep
                               *** you can manipulate and have for example 1 second = 1000ms */
                    socket_write($client,encode("You are active! your pc is awakend"));
                    $_SESSION['prev_time'] = $jsTime; /** saving newly sent time as previous time for future testing whcih will happen in two seconds in our case*/
                }else { /** if it is more than 3 seconds it means that javascript setInterval function was paused and resumed after 3 seconds 
                            ** So it means that it was at sleep because when your PC is at sleep/suspended/hibernate mode setINterval gets pauesd */
                    socket_write($client,encode("You are not active! your pc is at sleep"));
                    $_SESSION['prev_time'] = $jsTime;
                }
            }else { /** if we have not saved the previous time in session save it  */
                $_SESSION['prev_time'] = $jsTime;
            }

            print_r($_SESSION);

?>

और यहाँ php का पूरा कोड है:

<?php
//Code by: Nabi KAZ <www.nabi.ir>
session_abort();
// set some variables
$host = "127.0.0.1";
$port = 34237;
date_default_timezone_set("UTC");


// don't timeout!
set_time_limit(0);

// create socket
$socket = socket_create(AF_INET, SOCK_STREAM, 0)or die("Could not create socket\n");

// bind socket to port
$result = socket_bind($socket, $host, $port)or die("Could not bind to socket\n");

// start listening for connections
$result = socket_listen($socket, 20)or die("Could not set up socket listener\n");

$flag_handshake = false;
$client = null;
do {
    if (!$client) {
        // accept incoming connections
        // client another socket to handle communication
        $client = socket_accept($socket)or die("Could not accept incoming connection\n");
    }

    $bytes =  @socket_recv($client, $data, 2048, 0);
    if ($flag_handshake == false) {
        if ((int)$bytes == 0)
            continue;
        //print("Handshaking headers from client: ".$data."\n");
        if (handshake($client, $data, $socket)) {
            $flag_handshake = true;
        }
    }
    elseif($flag_handshake == true) {

        /*
        **** Main section for detectin sleep or not **
        */
        if ($data != "") {
            $decoded_data = unmask($data /* $data is actual data received from javascript socket */); //grabbing data and unmasking it | unmasking is for javascript sockets don't mind this
            print("< ".$decoded_data."\n");
            $response = strrev($decoded_data);
            $jsTime = (int) $decoded_data; /* time sent by javascript in MILISECONDS IN UNIX FORMAT  */
            if (isset($_SESSION['prev_time'])) { /** check if we have stored previous time in the session */
               $prev_time = (int) $_SESSION['prev_time']; /** grabbing the previous time from session */
               $diff = $jsTime-$prev_time; /** getting the difference newly sent time and previous time by subtracting */
               print("$jsTime - $prev_time = $diff"); /** printing the difference */
               if($diff<3000){ /** checking if difference is less than 3 second if it is it means pc was not at sleep
                               *** you can manipulate and have for example 1 second = 1000ms */
                    socket_write($client,encode("You are active! your pc is awakend"));
                    $_SESSION['prev_time'] = $jsTime; /** saving newly sent time as previous time for future testing whcih will happen in two seconds in our case*/
                }else { /** if it is more than 3 seconds it means that javascript setInterval function was paused and resumed after 3 seconds 
                            ** So it means that it was at sleep because when your PC is at sleep/suspended/hibernate mode setINterval gets pauesd */
                    socket_write($client,encode("You are not active! your pc is at sleep"));
                    $_SESSION['prev_time'] = $jsTime;
                }
            }else { /** if we have not saved the previous time in session save it  */
                $_SESSION['prev_time'] = $jsTime;
            }

            print_r($_SESSION);

           /*
        **** end of Main section for detectin sleep or not **
        */ 


        }
    }
} while (true);

// close sockets
socket_close($client);
socket_close($socket);
$client = null;
$flag_handshake = false;

function handshake($client, $headers, $socket) {

    if (preg_match("/Sec-WebSocket-Version: (.*)\r\n/", $headers, $match))
        $version = $match[1];
    else {
        print("The client doesn't support WebSocket");
        return false;
    }

    if ($version == 13) {
        // Extract header variables
        if (preg_match("/GET (.*) HTTP/", $headers, $match))
            $root = $match[1];
        if (preg_match("/Host: (.*)\r\n/", $headers, $match))
            $host = $match[1];
        if (preg_match("/Origin: (.*)\r\n/", $headers, $match))
            $origin = $match[1];
        if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $headers, $match))
            $key = $match[1];

        $acceptKey = $key.'258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
        $acceptKey = base64_encode(sha1($acceptKey, true));

        $upgrade = "HTTP/1.1 101 Switching Protocols\r\n".
            "Upgrade: websocket\r\n".
            "Connection: Upgrade\r\n".
            "Sec-WebSocket-Accept: $acceptKey".
            "\r\n\r\n";

        socket_write($client, $upgrade);
        return true;
    } else {
        print("WebSocket version 13 required (the client supports version {$version})");
        return false;
    }
}

function unmask($payload) {
    $length = ord($payload[1]) & 127;

    if ($length == 126) {
        $masks = substr($payload, 4, 4);
        $data = substr($payload, 8);
    }
    elseif($length == 127) {
        $masks = substr($payload, 10, 4);
        $data = substr($payload, 14);
    }
    else {
        $masks = substr($payload, 2, 4);
        $data = substr($payload, 6);
    }

    $text = '';
    for ($i = 0; $i < strlen($data); ++$i) {
        $text .= $data[$i] ^ $masks[$i % 4];
    }
    return $text;
}

function encode($text) {
    // 0x1 text frame (FIN + opcode)
    $b1 = 0x80 | (0x1 & 0x0f);
    $length = strlen($text);

    if ($length <= 125)
        $header = pack('CC', $b1, $length);
    elseif($length > 125 && $length < 65536)$header = pack('CCS', $b1, 126, $length);
    elseif($length >= 65536)
    $header = pack('CCN', $b1, 127, $length);

    return $header.$text;
}

नोट पढ़ें आईटी: $new_timeचर $jsTimeकोड में है

फोल्डर बनाएं और इसे फाइलों में कॉपी और पेस्ट करें। कमांड के साथ php सॉकेट चलाएं: php -f server_socket.php लोकलहोस्ट पर जाएं और यह देखने के लिए ओपन कंसोल का परीक्षण करें कि यह आपको "आप सक्रिय नहीं हैं" या "आप सक्रिय नहीं हैं" संदेश कहेंगे (जब आप नींद से आते हैं); आपका निष्पादक तब होगा जब उपयोगकर्ता नींद से आएगा, जब वे नींद के कारण नहीं होंगे, उस समय सब कुछ पेजफाइल (विंडोज़) या स्वैप (लाइनक्स) में कैश्ड है


फोल्डर बनाएं और इसे फाइलों में कॉपी और पेस्ट करें। कमांड के साथ php सॉकेट चलाएं: php -f server_socket.php लोकलहोस्ट पर जाएं और यह देखने के लिए ओपन कंसोल का परीक्षण करें कि यह आपको "आप सक्रिय नहीं हैं" या "आप सक्रिय नहीं हैं" संदेश कहेंगे (जब आप नींद से आते हैं); आपका निष्पादक तब होगा जब उपयोगकर्ता नींद से आएगा जब वे नींद के कारण नहीं होंगे, उस समय सब कुछ पेजफाइल (विंडोज़) या स्वैप (लाइनक्स) में कैश्ड है
डाटो डीटी

0

मुझे लगता है कि मेरे पास एक विचार है, आपने इस बारे में बहुत चर्चा की है कि बैंक लॉगिन / लॉगआउट सिस्टम कैसे काम करता है।

केस -1: यदि उपयोगकर्ता सक्रिय है तो असीमित समय के लिए उपयोगकर्ता के लिए वेबपेज का उपयोग

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

अब, सामने से आप उपयोगकर्ता गतिविधि को अपने बैकएंड पर भेज सकते हैं (सॉकेट या लंबे समय के मतदान का उपयोग करके भेजा जा सकता है), जो मूल रूप से टाइमर को रीसेट करेगा और उपयोगकर्ता जिस भी समय चाहें, वेबपृष्ठ का सक्रिय रूप से उपयोग कर सकते हैं।

यदि उपयोगकर्ता अपने पीसी को नींद में रखते हैं, तो टाइमर रीसेट नहीं होगा और टाइमर समाप्त होने पर आप सत्र को अमान्य कर सकते हैं।

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

मैं आशान्वित हूं कि इससे आपको सहायता मिलेगी। अगर आपको कोई सवाल है तो मुझे बताएं।


-1

अगर मशीन सो गई तो पता लगाने के लिए मैंने एक स्क्रिप्ट लिखी। आइडिया यह है कि जब मशीन नींद के मूड में होगी तो सभी स्क्रिप्ट बंद हो जाएंगे। इसलिए अगर हम एक टाइमइंटरवल के भीतर वर्तमान समय का ट्रैक रखें। हर बार timeInterval वर्तमान समय को घटा देता है (-) नया समय timeInterval के काफी पास होना चाहिए। अगर हम जाँच करना चाहते हैं कि क्या टाइमर X समय के लिए निष्क्रिय था, तो हम जाँच सकते हैं कि क्या समय का अंतर X से अधिक है।

यदि कंप्यूटर को 15 से अधिक के लिए सोने के लिए रखा गया था तो उदाहरण ब्लो चेक। कृपया ध्यान दें कि जब आप कंप्यूटर को सोते हैं तो यह सभी प्रोसेसर के बारे में विचार करने के लिए एक और अतिरिक्त 15s लेते हैं। (जब मेरा पीसी पर परीक्षण किया गया)।

(function() {
    this.SleepTimer = function() {
        // console.log('sleep timer initiated');
        // Create global element references
        this.sleepTimer = null;
        this.maxTime = null;
        this.curDate = null;
        this.newDate = null;
        this.timer = null;
        this.timeInterval = 1000;

        this.sleepTimer = new CustomEvent("sleepTimer", {
		    "detail": {
		    	"maxTime":this.maxTime,
				"idelFor": this.newDate - this.curDate,
				"timer": this.timer
			}
		});

        // Define option defaults
        var defaults = {
            maxTime: 10000,
            timeInterval: 1000,
            autoStart: true,
            console: false,
            onStart: null,
            onIdel: null
        }
        // Create options by extending defaults with the passed in arugments
        if (arguments[0] && typeof arguments[0] === "object") {
            this.options = extendDefaults(defaults, arguments[0]);
        }
        if (this.options.timeInterval) {
            this.timeInterval = Math.max(1000, this.options.timeInterval);
            this.maxTime = Math.max(this.options.maxTime, 10000);
        } else {
        	this.options = defaults;
        }

        if(this.options.autoStart === true) this.start()
        // Utility method to extend defaults with user options
        
    }
    function extendDefaults(source, properties) {
        var property;
        for (property in properties) {
            if (properties.hasOwnProperty(property)) {
                source[property] = properties[property];
            }
        }
        return source;
    }
    SleepTimer.prototype.start = function(){
        var _ = this;
    	this.options.onStart()
        this.curDate = Date.now();

        this.timer = setInterval(function() {
            _.newDate = Date.now();
            var diff = _.newDate - _.curDate;

            // for debugging
            if(_.options.console && diff > _.timeInterval){
            	console.log('Your PC was idel for ' + diff / 1000 + 's of ' + _.maxTime /1000 + 's. TimeInterval is set to ' + _.timeInterval / 1000 + 's');
            }
            
            if (diff < _.maxTime) {
                _.curDate = _.newDate;
            } else {
            	_.options.onIdel();
                // alert('You have been idle for ' + diff / 1000 + 's');
                clearTimeout(_.timer);
            }
        }, this.timeInterval); // seconds
    }
}());

var sleepTimer = new SleepTimer({
	maxTime: 15000,
	console: true,
	onStart: function(){
		console.log('sleepTimer started.');
	},
	onIdel: function(){
		alert('Your session expired! Please login again.');
	}
});


कृपया समझाएं कि यह काम क्यों नहीं करेगा, अगर यह आपके मामले में नहीं है
लसिथ्स

-1

मैंने लैम्बडा ऑथोराइज़र, और रेडिस के साथ AWS Cognito का उपयोग करके सटीक समान आवश्यकता को लागू किया है, मैं इस स्तर पर कोड को साझा नहीं कर सकता, लेकिन मैं आपको सब कुछ बता सकता हूं कि इन घटकों के साथ इसे कैसे लागू किया जाता है, समान अवधारणाओं का उपयोग अन्य के साथ किया जा सकता है गैर एडब्ल्यूएस घटक।

सबसे पहले एक निष्क्रियता लॉगआउट को लागू करने के साथ, आपको इसे सर्वर साइड करना होगा, जैसे कि कोई व्यक्ति बस अपने कंप्यूटर को बंद कर देता है, फ्रंट-एंड वेबसाइट उन्हें लॉग आउट नहीं करेगी। मैंने ACTIVEउपयोगकर्ताओं की अवधारणा का उपयोग किया । जब उपयोगकर्ता सफलतापूर्वक प्रमाणित हो जाते हैं, तो मैं Redis में 15 मिनट के एक TTL के साथ उनकी कुंजी के usernameमान के साथ एक प्रविष्टि ACTIVE(यह उपयोगकर्ता नाम + सत्रीय हो सकता है अगर आप एक ही समय में दिए गए उपयोगकर्ता के लिए कई सत्रों की अनुमति देना चाहते हैं) के साथ संग्रहीत करते हैं।

अपने कस्टम Authorizers में जब कोई उपयोगकर्ता है ACTIVEऔर वे एक वैध टोकन है, मैं संरक्षित संसाधन के लिए उन्हें एक्सेस देने और सबसे महत्वपूर्ण बात, मैं के साथ Redis में एक और डाल कर usernameऔर ACTIVE

जब भी उपयोगकर्ता लॉग आउट करता है, मैं उन्हें अपने पहचान प्रबंधन समाधान (कॉग्निटो) में लॉग आउट करता हूं और मैं उन्हें चिह्नित करता हूं INACTIVE। ध्यान दें कि यदि कोई उपयोगकर्ता 15 मिनट के भीतर API को हिट नहीं करता है, तो ACTIVEउनके पास अब उनके उपयोगकर्ता नाम के खिलाफ प्रविष्टि नहीं होगी और वह अब API तक नहीं पहुंच पाएगा और फिर से साइन इन करना होगा, जिसके लिए उन्हें रीडायरेक्ट किया जाएगा।

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

यह भी महत्वपूर्ण है कि आप यह सुनिश्चित करें कि जो भी आप स्टोर करने के लिए उपयोग करते हैं यदि कोई दिया गया उपयोगकर्ता ACTIVEअत्यधिक उपलब्ध है और विफलता की स्थिति में जल्दी ठीक हो जाएगा।

कैश स्टोर का उपयोग करने का तरीका इस तरह से है कि टोकन अमान्यकरण OAuth2 जैसे सांख्यिकीय प्राधिकरण प्रोटोकॉल के लिए वापस कर दिया गया है।

हम कुछ महीनों के लिए इस दृष्टिकोण का उपयोग कर रहे हैं, यह हमारे लिए ठीक काम करता है, इसे संभालने के लिए थोड़ा कष्टप्रद आवश्यकता हो सकती है, मुझे AWS दुनिया में उम्मीद थी कि बाहर उपयोग करने के लिए तैयार होगा इस के लिए बॉक्स समाधान लेकिन वहाँ बात करने के लिए कोई नहीं था।


हम एक पेन टेस्ट से भी बच गए (; यह वह जगह है जहाँ से हमारी आवश्यकता शुरू में आई थी, हमारा आवेदन एक वित्तीय सेवा आधारित उत्पाद है, और हमें इसे आवश्यकता के रूप में लागू करना पड़ा।
Snickers3192
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.