कुकीज़ सर्वर-साइड को हटाने का सही तरीका


141

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

तो मैं सर्वर से कुछ इस तरह भेजना होगा:

Set-Cookie: token=$2a$12$T94df7ArHkpkX7RGYndcq.fKU.oRlkVLOkCBNrMilaSWnTcWtCfJC; path=/;

जो सभी ब्राउज़र पर काम करता है। फिर एक कुकी को हटाने के लिए मैं expires1 जनवरी 1970 के लिए फ़ील्ड सेट के साथ एक समान कुकी भेजता हूं

Set-Cookie: token=$2a$12$T94df7ArHkpkX7RGYndcq.fKU.oRlkVLOkCBNrMilaSWnTcWtCfJC; path=/; expires=Thu, Jan 01 1970 00:00:00 UTC; 

और यह फ़ायरफ़ॉक्स पर ठीक काम करता है, लेकिन IE या सफारी पर कुकी को हटाता नहीं है।

तो एक कुकी को हटाने का सबसे अच्छा तरीका क्या है (जावास्क्रिप्ट के बिना अधिमानतः)? सेट-ऑफ-ए-एक्सपायर-इन-द-पास्ट विधि भारी लगती है। और यह भी एफएफ में क्यों काम करता है लेकिन आईई या सफारी में नहीं?


जवाबों:


209

एक ही कुकी मूल्य को ; expiresजोड़कर भेजने से कुकी नष्ट नहीं होगी।

खाली मान सेट करके कुकी को अमान्य करें और एक expiresफ़ील्ड भी शामिल करें:

Set-Cookie: token=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT

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


52
मैं खाली पाठ का उपयोग बकवास के रूप में करने की सलाह "deleted"
दूंगा

8
@ आलोक जी, आप सही हैं। मज़ेदार है कि यह पहले नहीं देखा गया है, उम्मीद है कि यह बहुत अधिक मुद्दा नहीं बना। yegor256, ज्यादातर मामलों में एक खाली मान काम करना चाहिए। संबंधित: कुछ लोग आश्चर्यचकित हो सकते हैं कि इस शीर्षक को भेजने के बाद भी उनकी कुकीज़ क्यों नहीं हटाई गईं। उस स्थिति में, अन्य डोमेन से कुकीज़ पर एक नज़र है। उदाहरण के लिए, हटाने के बाद foo=bar; domain=www.example.com, एक अन्य कुकी foo=qux; domain=.example.comका उपयोग किया जाएगा।
लेकेनस्टाइन

3
"ग्राहक ब्राउज़र को इस तरह से कॉन्फ़िगर कर सकता है कि कुकी बनी रहे, भले ही वह समाप्त हो गई हो। ऊपर वर्णित मान सेट करने से यह समस्या हल हो जाएगी।" क्या कुकी को "हटाए गए" सामग्री को सेट करने के आपके अनुरोध को अनदेखा करने के लिए क्लाइंट ब्राउज़र को कॉन्फ़िगर नहीं कर सकता है? आपके पास क्लाइंट को ऐसा कुछ भी करने के लिए मजबूर करने का कोई तरीका नहीं है जिसे वह नहीं करना चाहता।
Ajedi32

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

2
-1 क्योंकि मैंने कुकी समाप्ति को अनदेखा करने के लिए ब्राउज़र को कॉन्फ़िगर करने का एक तरीका कभी नहीं देखा है, और यह असंबद्ध है कि कोई भी ब्राउज़र मौजूद है जो इस तरह का विकल्प प्रदान करता है। क्या अधिक है, आपके जवाब का पहला वाक्य, @ DaveJarvis के बोल्ड एडिट के बाद, अब किसी भी बड़े ब्राउज़र या किसी भी कल्पना-योग्य उपयोगकर्ता एजेंट के लिए बिल्कुल गलत है। tools.ietf.org/search/rfc6265#section-5.3 तय करता है कि "उपयोगकर्ता एजेंट को कुकी स्टोर से सभी एक्सपायर्ड कुकीज़ को बाहर निकालना चाहिए, अगर किसी भी समय, कुकी स्टोर में एक एक्सपायर कुकी मौजूद है।" और मेरे ज्ञान का सबसे अच्छा है कि वास्तव में हर ब्राउज़र क्या करता है।
मार्क अमेरी

46

मेरे इस उत्तर को लिखने के समय, इस प्रश्न का स्वीकृत उत्तर यह प्रतीत होता है कि प्रतिस्थापन कुकी प्राप्त करते समय ब्राउज़र को कुकी को हटाने की आवश्यकता नहीं होती है जिसका Expiresमूल्य अतीत में है। वह दावा झूठा है। स्थापना Expiresअतीत में होना करने के लिए मानक, कल्पना अनुरूप एक कुकी को हटाने का तरीका है, और उपयोगकर्ता एजेंटों यह सम्मान करने के लिए कल्पना के लिए आवश्यक हैं।

Expiresकुकी को हटाने के लिए अतीत में एक विशेषता का उपयोग करना सही है और युक्ति द्वारा निर्धारित कुकीज़ को हटाने का तरीका है। RFC 6255 राज्यों का उदाहरण अनुभाग :

अंत में, कुकी को निकालने के लिए, सर्वर अतीत में समाप्ति तिथि के साथ सेट-कुकी शीर्षलेख लौटाता है। सर्वर कुकी को निकालने में तभी सफल होगा जब सेट-कुकी शीर्षलेख में पथ और डोमेन विशेषता कुकी के उपयोग के दौरान उपयोग किए गए मानों से मेल खाती हो।

उपयोगकर्ता एजेंट आवश्यकताओं अनुभाग निम्न आवश्यकताओं को, जो एक साथ प्रभाव है कि एक कुकी तुरंत मिटा दिया जाना चाहिए अगर उपयोगकर्ता एजेंट एक ही नाम जिसका समाप्ति तिथि अतीत में है के साथ एक नया कुकी प्राप्त करता है शामिल

  1. अगर [नई कुकी प्राप्त करते समय] कुकी स्टोर में एक ही नाम, डोमेन, और पथ के साथ एक कुकी होती है, जैसा कि नई बनी कुकी:

    1. ...
    2. ...
    3. पुराने-कुकी के निर्माण-समय से मेल खाने के लिए नई बनाई गई कुकी के निर्माण-समय को अपडेट करें।
    4. कुकी स्टोर से पुराने-कुकी को हटा दें।
  2. कुकी स्टोर में नई बनाई गई कुकी डालें।

यदि कुकी की अतीत में समाप्ति तिथि है, तो एक कुकी "समाप्त हो गई" है।

उपयोगकर्ता एजेंट को कुकी स्टोर से सभी समयसीमा समाप्त कुकीज़ को बाहर निकालना चाहिए, अगर किसी भी समय, कुकी स्टोर में एक समय सीमा समाप्त कुकी मौजूद है।

अंक 11-3, 11-4, और 12 एक साथ ऊपर का मतलब है कि जब एक नया कुकी एक ही नाम, डोमेन और पथ के साथ प्राप्त होता है, तो पुरानी कुकी को बाहर निकाला जाना चाहिए और नई कुकी के साथ प्रतिस्थापित किया जाना चाहिए। अंत में, एक्सपायर कुकीज़ के बारे में नीचे दी गई बात आगे बताती है कि ऐसा करने के बाद, नई कुकी को भी तुरंत निकाल देना चाहिए । कल्पना इस बिंदु पर ब्राउज़रों के लिए कोई wiggle कमरा प्रदान करती है; यदि कोई ब्राउज़र उपयोगकर्ता को कुकी समाप्ति को अक्षम करने का विकल्प देने की पेशकश करता है, जैसा कि स्वीकृत उत्तर कुछ ब्राउज़रों का सुझाव है, तो यह कल्पना का उल्लंघन होगा। (इस तरह की सुविधा का बहुत कम उपयोग होता है, और जहां तक ​​मुझे पता है कि यह किसी भी ब्राउज़र में मौजूद नहीं है।)

फिर, इस प्रश्न के ओपी ने इस दृष्टिकोण को विफल क्यों माना? हालाँकि मैंने इसके व्यवहार की जाँच करने के लिए Internet Explorer की एक प्रति को नहीं हटाया है, मुझे संदेह है कि यह ओपी का Expiresमूल्य विकृत था! उन्होंने इस मूल्य का उपयोग किया:

expires=Thu, Jan 01 1970 00:00:00 UTC;

हालाँकि, यह दो तरीकों से वाक्यविन्यास रूप से अमान्य है।

युक्ति का सिंटैक्स अनुभाग यह निर्धारित करता है कि Expiresविशेषता का मान होना चाहिए

rfc1123 -date, जिसे [RFC2616], धारा 3.3.1 में परिभाषित किया गया है

ऊपर दिए गए दूसरे लिंक के बाद, हम इसे प्रारूप के उदाहरण के रूप में देखते हैं:

Sun, 06 Nov 1994 08:49:37 GMT

और पाते हैं कि वाक्य रचना परिभाषा ...

  1. यह आवश्यक है कि तिथियां दिन के महीने के प्रारूप में लिखी जाएं , प्रश्न पूछने वाले द्वारा उपयोग किए गए महीने के प्रारूप के अनुसार नहीं ।

    विशेष रूप से, यह rfc1123-dateनिम्नानुसार परिभाषित करता है:

    rfc1123-date = wkday "," SP date1 SP time SP "GMT"
    

    और date1इस तरह परिभाषित करता है:

    date1        = 2DIGIT SP month SP 4DIGIT
                 ; day month year (e.g., 02 Jun 1982)
    

तथा

  1. UTCएक समयक्षेत्र के रूप में अनुमति नहीं है ।

    इस प्रारूप में क्या समय-सीमा ऑफसेट स्वीकार्य हैं, इस बारे में निम्नलिखित कथन शामिल हैं:

    बिना किसी अपवाद के सभी HTTP दिनांक / समय टिकटों को ग्रीनविच मीन टाइम (GMT) में दर्शाया जाना चाहिए।

    अगर हम इस डेटाटाइम प्रारूप की मूल कल्पना में गहराई से खुदाई करते हैं, तो हम https://tools.ietf.org/html/rfc822 में इसके प्रारंभिक नमूने में और अधिक खोज करते हैं, सिंटैक्स अनुभाग "UT" को सूचीबद्ध करता है (जिसका अर्थ है "सार्वभौमिक समय" ) एक संभव मूल्य के रूप में है, लेकिन करता है नहीं सूची नहीं यूटीसी (समन्वित यूनिवर्सल समय) वैध के रूप में। जहाँ तक मुझे पता है, इस तिथि प्रारूप में "UTC" का उपयोग करना कभी भी मान्य नहीं रहा है; 1982 में जब प्रारूप पहली बार निर्दिष्ट किया गया था, तो यह एक वैध मूल्य नहीं था, और HTTP युक्ति ने "GMT" के अलावा सभी "ज़ोन" मूल्यों के उपयोग पर प्रतिबंध लगाते हुए प्रारूप के कड़ाई से अधिक प्रतिबंधात्मक संस्करण को अपनाया है ।

सवाल यहाँ प्रश्नकर्ता बजाय एक का इस्तेमाल किया था, तो Expiresजैसे विशेषता यह है, तो:

expires=Thu, 01 Jan 1970 00:00:00 GMT;

तब यह संभवतः काम किया होगा।


15

"समाप्ति" को एक अंतिम तिथि पर सेट करना कुकी को हटाने का मानक तरीका है।

आपकी समस्या शायद इसलिए है क्योंकि तिथि प्रारूप पारंपरिक नहीं है। IE शायद GMT की अपेक्षा करता है।


2

"एक्सपायर" के बजाय मैक्स-एज = -1 का उपयोग करें। यह कम है, वाक्यविन्यास के बारे में कम picky, और मैक्स-एज वैसे भी समाप्त हो रहा है पर पूर्वता लेता है।


-1

ग्लासफिश जर्सी जेएएक्स-आरएस कार्यान्वयन के लिए मैंने इस मुद्दे को हल किया है सामान्य विधि सभी सामान्य मापदंडों का वर्णन कर रही है। कम से कम तीन मापदंडों के बराबर होना चाहिए: नाम (= "नाम"), पथ (= "/") और डोमेन (= नाम):

public static NewCookie createDomainCookie(String value, int maxAgeInMinutes) {
    ZonedDateTime time = ZonedDateTime.now().plusMinutes(maxAgeInMinutes);
    Date expiry = time.toInstant().toEpochMilli();
    NewCookie newCookie = new NewCookie("name", value, "/", null, Cookie.DEFAULT_VERSION,null, maxAgeInMinutes*60, expiry, false, false);
    return newCookie;
}

और इसे कुकी सेट करने के सामान्य तरीके का उपयोग करें:

NewCookie domainNewCookie = RsCookieHelper.createDomainCookie(token, 60);
Response res = Response.status(Response.Status.OK).cookie(domainNewCookie).build();

और कुकी को हटाने के लिए:

NewCookie domainNewCookie = RsCookieHelper.createDomainCookie("", 0);
Response res = Response.status(Response.Status.OK).cookie(domainNewCookie).build();

मेरे लिए जब मैं अधिकतम 0 सेट करता हूं, तो यह अधिकतम-आयु = 0 के साथ एक कुकी को आउटपुट करता है जिसे क्रोम नजरअंदाज करता है। में आरएफसी 6265 खंड 4.1.1 यह "गैर शून्य अंकों" मैक्स-उम्र की वाक्य रचना निर्दिष्ट करता है। यही कारण हो सकता है। हालाँकि, @ जोश 13 के अनुसार, खंड 5.2.2 शून्य से कम या उसके बराबर मूल्यों की व्याख्या करने की बात करता है। तो यह खुद को वहाँ विरोधाभास की तरह है ...
Matthijs वेसल्स

मुझे विवरण नहीं पता है, लेकिन जोड़ी में ये मूल्य वास्तव में क्रोम और अन्य ब्राउज़रों में काम कर रहे हैं: maxAgeInMinutes * 60, समाप्ति।
RoutesMaps.com

1
@MatthijsWessels अच्छा कैच! मैं थोड़ा गहरा खोदा, और स्पष्ट विरोधाभास वास्तव में जानबूझकर है, जैसा कि rfc-editor.org/errata/eid3430 पर इरेटा में दिया गया है । "इंटरऑपरेबिलिटी को अधिकतम करने के लिए", उपयोगकर्ता एजेंटों को एक शून्य या नकारात्मक की व्याख्या करने की आवश्यकता होती है Max-Ageक्योंकि जल्द से जल्द प्रतिनिधित्व करने योग्य तारीख और समय होता है, लेकिन सर्वर को ऐसा Max-Ageमूल्य भेजने से मना किया जाता है । मुझे लगता है कि लेखकों को दोनों मौजूदा ग्राहकों के बारे में पता था जो संभाल नहीं सकते थे Max-Age=0और सर्वर ने इसे उस समय भेजा था जब उन्होंने कल्पना लिखी थी, और दोनों छोर से समस्या को कम करने की कोशिश की।
मार्क अमेरी

@ Crimean.us मैं अब और भी नहीं दोहरा सकता। हो सकता है कि मैंने कुछ गलत किया हो
Matthijs Wessels

@ मैक्स-एज = 0 को नजरअंदाज करने के साथ @MatthijsWessels समस्या ZonedDateTime.now ()। PlusMinutes (maxAgeInMinute) की समाप्ति तिथि निर्धारित करके मेरे उदाहरण में तय की गई है। MaxAgeInMinutes = 0 के लिए यह वर्तमान डेटाटाइम है। यह कोड वास्तविक वेब अनुप्रयोग में लंबे समय तक काम कर रहा है।
RoutesMaps.com
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.