जवाबों:
यह एक शीघ्र है:
आपको लगता है कि यह होना चाहिए, लेकिन वास्तव में यह बिल्कुल नहीं है!
कुकी नाम और मूल्य दोनों में अनुमत वर्ण क्या हैं?
प्राचीन नेटस्केप कुकी_स्पेक के अनुसार संपूर्ण NAME=VALUE
स्ट्रिंग है:
अर्ध-बृहदान्त्र, अल्पविराम और सफेद स्थान को छोड़कर पात्रों का एक क्रम।
तो -
काम करना चाहिए, और यह मेरे द्वारा प्राप्त किए गए ब्राउज़रों में ठीक प्रतीत होता है; आप इससे परेशान कहाँ हैं?
उपरोक्त के निहितार्थ द्वारा:
=
शामिल करने के लिए कानूनी है, लेकिन संभावित रूप से अस्पष्ट है। ब्राउज़र हमेशा =
स्ट्रिंग में पहले प्रतीक पर नाम और मूल्य को विभाजित करते हैं , इसलिए व्यवहार में आप =
VALUE में एक प्रतीक रख सकते हैं लेकिन NAME नहीं।उल्लेख नहीं किया गया है, क्योंकि नेटस्केप चश्मा लिखने में भयानक थे, लेकिन लगता है कि वे लगातार ब्राउज़र द्वारा समर्थित हैं:
या तो NAME या VALUE रिक्त स्ट्रिंग्स हो सकता है
यदि =
स्ट्रिंग में कोई प्रतीक नहीं है , तो ब्राउज़र इसे खाली-स्ट्रिंग नाम के साथ कुकी के रूप में मानते हैं, अर्थात Set-Cookie: foo
जैसा है Set-Cookie: =foo
।
जब ब्राउज़र एक खाली नाम के साथ कुकी का उत्पादन करते हैं, तो वे बराबर चिह्न को छोड़ देते हैं। इसलिए Set-Cookie: =bar
भूल जाते हैं Cookie: bar
।
अल्पविराम और नाम और मूल्यों में रिक्त स्थान वास्तव में काम करने लगते हैं, हालांकि बराबर चिह्न के चारों ओर रिक्त स्थान को छंटनी की जाती है
(नियंत्रण वर्ण \x00
के लिए \x1F
प्लस \x7F
) की अनुमति नहीं है
क्या उल्लेख नहीं है और ब्राउज़र पूरी तरह से असंगत हैं, गैर- ASCII (यूनिकोड) वर्ण हैं:
तो व्यवहार में आप कुकीज़ में गैर- ASCII वर्णों का उपयोग नहीं कर सकते। यदि आप यूनिकोड, नियंत्रण कोड या अन्य मनमाने ढंग से बाइट अनुक्रमों का उपयोग करना चाहते हैं, तो कुकी_स्पेक आपकी स्वयं की चुनने की एक तदर्थ एन्कोडिंग योजना का उपयोग करता है और encodeURIComponent
एक उचित विकल्प के रूप में यूआरएल-एन्कोडिंग (जावास्क्रिप्ट द्वारा निर्मित ) का सुझाव देता है ।
वास्तविक मानकों के संदर्भ में , कुकी व्यवहार को संहिताबद्ध करने के लिए कुछ प्रयास किए गए हैं, लेकिन वास्तव में वास्तव में वास्तविक दुनिया को प्रतिबिंबित नहीं करता है।
RFC 2109 मूल नेटस्केप कुकी_स्पेक को संहिताबद्ध और ठीक करने का एक प्रयास था। इस मानक में कई और विशेष वर्णों को अस्वीकृत कर दिया जाता है, क्योंकि यह RFC 2616 टोकन का उपयोग करता है ( -
यह अभी भी वहां अनुमति है), और अन्य वर्णों के साथ एक उद्धृत-स्ट्रिंग में केवल मान निर्दिष्ट किया जा सकता है। किसी भी ब्राउज़र ने कभी भी सीमाओं को लागू नहीं किया, उद्धृत स्ट्रिंग्स और भागने की विशेष हैंडलिंग या इस विशेषता में नई विशेषताएं।
RFC 2965 इस पर एक और चल रहा था, 2109 तक टिक गया और 'वर्जन 2 कुकीज' स्कीम के तहत और फीचर्स जोड़े। किसी ने कभी भी उस पर कोई अमल नहीं किया। इस युक्ति में पहले संस्करण के समान टोकन-और-उद्धृत-स्ट्रिंग सीमाएँ हैं और यह केवल बकवास का अधिक भार है।
RFC 6265 ऐतिहासिक गड़बड़ को साफ करने के लिए HTML5-युग का प्रयास है। यह अभी भी वास्तविकता से बिल्कुल मेल नहीं खाता है, लेकिन यह बहुत बेहतर है, फिर पहले का प्रयास-यह कम से कम एक ब्राउज़र का समर्थन करता है, जो किसी भी वाक्यविन्यास को पेश करने का समर्थन नहीं करता है, जो काम करने वाला है लेकिन (पिछले उद्धृत-स्ट्रिंग की तरह) नहीं ।
6265 में कुकी का नाम अभी भी RFC 2616 के रूप में निर्दिष्ट है token
, जिसका अर्थ है कि आप अल्फ़ान्यूम्स प्लस से चुन सकते हैं:
!#$%&'*+-.^_`|~
कुकी मान में यह औपचारिक रूप से (ब्राउज़रों द्वारा फ़िल्टर किया गया) नियंत्रण वर्ण और (असंगत रूप से कार्यान्वित) गैर-ASCII वर्णों पर प्रतिबंध लगाता है। यह अंतरिक्ष, कॉमा और अर्धविराम पर कुकी_स्पेक के निषेध को बरकरार रखता है, साथ ही किसी भी गरीब बेवकूफों के साथ संगतता के लिए जो वास्तव में पहले के RFC को लागू करते थे, इसने बैकस्लैश और उद्धरणों पर प्रतिबंध लगा दिया था, उद्धरणों के अलावा पूरे मूल्य को लपेटते हुए (लेकिन उस स्थिति में उद्धरण अभी भी भाग माना जाता है। मूल्य, एन्कोडिंग योजना नहीं)। ताकि आपको अल्फ़ान्यूम्स के साथ छोड़ दिया जाए:
!#$%&'()*+-./:<=>?@[]^_`{|}~
वास्तविक दुनिया में हम अभी भी मूल-और सबसे खराब नेटस्केप कुकी_स्पेक का उपयोग कर रहे हैं, इसलिए कुकीज़ का सेवन करने वाले कोड को बहुत अधिक कुछ भी तैयार करने के लिए तैयार किया जाना चाहिए, लेकिन कुकीज़ का उत्पादन करने वाले कोड के लिए आरएफसी 6265 में सबसेट के साथ रहना उचित है।
Name="Va;lue"; max-age...
। यह ब्राउज़रों में काम नहीं करता है और इसे RFC 6265 में अनुमति नहीं है, जो 2965 को बदलने का प्रस्ताव है और वास्तविकता को थोड़ा बेहतर दिखाने की कोशिश करता है।
1*<any CHAR except CTLs or separators>
और विभाजक हैं (
, )
, <
, >
, @
, ,
, ;
, :
, \
, "
, /
, [
, ]
, ?
, =
, {
, }
, SP
और HT
, इसलिए कुकी नाम alphanums होना चाहिए प्लस!#$%&'*+-.?^_`|~
ASP.Net में आप System.Web.HttpUtility
कुकी को लिखने से पहले कुकी मान को सुरक्षित रूप से एनकोड करने के लिए उपयोग कर सकते हैं और इसे बाहर पढ़ने पर अपने मूल रूप में बदल सकते हैं।
// Encode
HttpUtility.UrlEncode(cookieData);
// Decode
HttpUtility.UrlDecode(encodedCookieData);
यह एम्परसैंड्स को रोक देगा और नाम / मूल्य जोड़े के एक गुच्छा में एक मूल्य को विभाजित करने वाले संकेतों के बराबर होता है क्योंकि यह एक कुकी के लिए लिखा जाता है।
मुझे लगता है कि यह आम तौर पर विशिष्ट ब्राउज़र है। सुरक्षित पक्ष पर होने के लिए, बेस 64 एक JSON ऑब्जेक्ट को एनकोड करता है, और उसमें सब कुछ स्टोर करता है। इस तरह से आपको बस इसे डिकोड करना होगा और JSON को पार्स करना होगा। बेस 64 में उपयोग किए जाने वाले सभी वर्णों को ठीक से खेलना चाहिए, यदि सभी ब्राउज़र नहीं।
यहाँ यह संभव के रूप में कुछ शब्दों में है । ऐसे चरित्रों पर ध्यान केंद्रित करें, जिनसे बचने की आवश्यकता नहीं है:
कुकीज़ के लिए:
abdefghijklmnqrstuvxyzABDEFGHIJKLMNQRSTUVXYZ0123456789!#$%&'()*+-./:<>?@[]^_`{|}~
Urls के लिए
abdefghijklmnqrstuvxyzABDEFGHIJKLMNQRSTUVXYZ0123456789.-_~!$&'()*+,;=:@
कुकीज़ और urls (प्रतिच्छेदन) के लिए
abdefghijklmnqrstuvxyzABDEFGHIJKLMNQRSTUVXYZ0123456789!$&'()*+-.:@_~
इसी तरह आप जवाब दें।
ध्यान दें कि कुकीज़ के लिए, = को हटा दिया गया है क्योंकि यह आमतौर पर कुकी मान को सेट करने के लिए उपयोग किया जाता है।
Urls के लिए यह = रखा गया था। चौराहे स्पष्ट रूप से बिना है।
var chars = "abdefghijklmnqrstuvxyz"; chars += chars.toUpperCase() + "0123456789" + "!$&'()*+-.:@_~";
बाहर निकलना अभी भी घटता है और अप्रत्याशित रूप से घटित होता है, विशेष रूप से जावा कुकी वातावरण में जहां कुकी दोहरे उद्धरणों के साथ लिपटी होती है यदि यह अंतिम पात्रों का सामना करती है।
इसलिए सुरक्षित रहने के लिए, बस A-Za-z1-9 का उपयोग करें। यही मैं करने जा रहा हूं।
अप्रैल 2011 में प्रकाशित नए rfc6265 :
cookie-header = "Cookie:" OWS cookie-string OWS
cookie-string = cookie-pair *( ";" SP cookie-pair )
cookie-pair = cookie-name "=" cookie-value
cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
; US-ASCII characters excluding CTLs,
; whitespace DQUOTE, comma, semicolon,
; and backslash
यदि आप @bobince उत्तर को देखते हैं तो आप देखते हैं कि नए प्रतिबंध अधिक सख्त हैं।
कुकीज़ विनिर्देशों के 2 संस्करण हैं
। संस्करण 0 कुकीज़ उर्फ नेटस्केप कुकीज़,
2. संस्करण 1 उर्फ आरएफसी 2965 कुकीज़
संस्करण 0 में कुकीज़ के नाम और मूल्य भाग अर्धविराम, अल्पविराम, विषुव चिह्न, और व्हाट्सएप को छोड़कर पात्रों के अनुक्रम हैं। , अगर दोहरे उद्धरण चिह्नों के साथ उपयोग नहीं किया जाता है तो
1 बहुत अधिक जटिल है आप इसे यहाँ देख सकते हैं
। इस संस्करण में नाम मान भाग के लिए चश्मा लगभग समान है सिवाय नाम $ संकेत के साथ शुरू नहीं हो सकता है
आईई और एज के साथ एक और दिलचस्प मुद्दा है। 1 से अधिक अवधि वाले नाम वाले कुकीज़ चुपचाप गिराए गए प्रतीत होते हैं। तो यह काम करता है:
cookie_name_a = valuea
जबकि यह गिरा दिया जाएगा
cookie.name.a = valuea
यह आसान है:
A <कुकी-नाम> नियंत्रण वर्ण (CTL), रिक्त स्थान, या टैब को छोड़कर कोई भी US-ASCII वर्ण हो सकता है। इसमें निम्नलिखित की तरह एक विभाजक वर्ण नहीं होना चाहिए: () <> @,; : \ "/ []? = {}।
एक <कुकी-मूल्य> वैकल्पिक रूप से दोहरे उद्धरण चिह्नों में सेट किया जा सकता है और सीटीएल, व्हाट्सएप, डबल उद्धरण, अल्पविराम, अर्धविराम और बैकस्लैश को छोड़कर किसी भी यूएस-एएससीआईआई पात्रों की अनुमति है। एन्कोडिंग: कई कार्यान्वयन कुकी मानों पर URL एन्कोडिंग करते हैं, हालांकि यह RFC विनिर्देशन के अनुसार आवश्यक नहीं है। यह उन आवश्यकताओं को संतुष्ट करने में मदद करता है जिनके बारे में पात्रों की अनुमति है।
लिंक: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Directives
एक और विचार। मैंने हाल ही में एक योजना लागू की है जिसमें एक PHP स्क्रिप्ट में पोस्ट किए गए कुछ संवेदनशील डेटा को एन्क्रिप्टेड कुकी के रूप में परिवर्तित करने और वापस करने के लिए आवश्यक है, जिसका उपयोग मैंने सोचा था कि सभी बेस 64 मानों का उपयोग 'सुरक्षित' की गारंटी है। इसलिए मैंने RC4 का उपयोग करके डेटा आइटमों को सावधानी से एन्क्रिप्ट किया। base64_encode के माध्यम से आउटपुट, और खुशी से कुकी को साइट पर लौटाया गया। परीक्षण तब तक अच्छा लग रहा था जब तक कि एक base64 एन्कोडेड स्ट्रिंग में "+" प्रतीक नहीं था। स्ट्रिंग को पेज कुकी को बिना किसी परेशानी के लिखा गया था। ब्राउज़र डायग्नोस्टिक का उपयोग करके मैं भी कर सकता था। सत्यापित करें कि कुकीज़ अपरिवर्तित लिखी गई थी। फिर जब एक बाद वाले पृष्ठ ने मेरे PHP को कॉल किया और $ _COOKIE सरणी के माध्यम से कुकी प्राप्त की, तो मुझे यह पता लगाने के लिए हतोत्साहित किया गया था कि स्ट्रिंग अब "+" चिन्ह को याद नहीं कर रही है। ASCII स्थान।
यह देखते हुए कि मैंने तब से इस परिदृश्य का वर्णन करते हुए कितनी समान अनसुलझे शिकायतों को देखा है, अक्सर कुकीज़ में मनमाने ढंग से डेटा को "सुरक्षित रूप से" स्टोर करने के लिए कई संदर्भों का उपयोग करते हुए, मैंने सोचा कि मैं इस समस्या को इंगित करता हूं और अपने कोडली कुडली समाधान की पेशकश करता हूं।
आपके द्वारा डेटा के एक टुकड़े पर जो भी एन्क्रिप्शन करना चाहते हैं, उसे करने के बाद, और फिर "कुकी-सुरक्षित" बनाने के लिए बेस 64_encode का उपयोग किया, इसके माध्यम से आउटपुट स्ट्रिंग चलाएं ...
// from browser to PHP. substitute troublesome chars with
// other cookie safe chars, or vis-versa.
function fix64($inp) {
$out =$inp;
for($i = 0; $i < strlen($inp); $i++) {
$c = $inp[$i];
switch ($c) {
case '+': $c = '*'; break; // definitly won't transfer!
case '*': $c = '+'; break;
case '=': $c = ':'; break; // = symbol seems like a bad idea
case ':': $c = '='; break;
default: continue;
}
$out[$i] = $c;
}
return $out;
}
यहाँ मैं केवल "+" (और मैंने तय किया "=") के साथ ही अन्य "कुकी सुरक्षित" पात्रों के साथ, पृष्ठ पर एन्कोडेड मान को कुकी के रूप में उपयोग करने से पहले। ध्यान दें कि संसाधित की जा रही स्ट्रिंग की लंबाई नहीं बदलती है। जब वही (या साइट पर कोई अन्य पृष्ठ) मेरी PHP स्क्रिप्ट को फिर से चलाता है, तो मैं इस कुकी को लापता पात्रों के बिना पुनर्प्राप्त कर पाऊंगा। मुझे सिर्फ कुकी को उसी फिक्स 64 () कॉल मी के माध्यम से वापस पास करना याद रखना है, और वहां से मैं इसे सामान्य बेस 64_डब्लू () के साथ डिकोड कर सकता हूं, इसके बाद आपकी योजना में जो भी डिक्रिप्शन है।
कुछ सेटिंग हो सकती हैं जिन्हें मैं PHP में बना सकता हूं जो कुकीज़ में इस्तेमाल किए गए आधार 64 स्ट्रिंग्स को बिना भ्रष्टाचार के PHP में वापस स्थानांतरित करने की अनुमति देता है। इस बीच में यह काम करता है। "+" एक "कानूनी" कुकी मूल्य हो सकता है, लेकिन अगर आपको पीएचपी (मेरे मामले में $ _COOKIE सरणी के माध्यम से) इस तरह के एक स्ट्रिंग को PHP में स्थानांतरित करने में सक्षम होने की कोई इच्छा है, तो मैं हटाने के लिए पुन: प्रसंस्करण का सुझाव दे रहा हूं अपमानजनक चरित्र, और पुनर्प्राप्ति के बाद उन्हें पुनर्स्थापित करें। चुनने के लिए बहुत सारे अन्य "कुकी सुरक्षित" अक्षर हैं।
यदि आप बाद में चर का उपयोग कर रहे हैं, तो आप पाएंगे कि सामान path
वास्तव में उच्चारण पात्रों को जाने देगा, लेकिन यह वास्तव में ब्राउज़र पथ से मेल नहीं खाएगा। इसके लिए आपको उन्हें URIEncode करना होगा। तो इस तरह से:
const encodedPath = encodeURI(myPath);
document.cookie = `use_pwa=true; domain=${location.host}; path=${encodedPath};`
तो "अनुमत" वर्ण, क्या कल्पना में है की तुलना में अधिक हो सकता है। लेकिन आपको कल्पना के भीतर रहना चाहिए, और सुरक्षित रहने के लिए यूआरआई-एन्कोडेड स्ट्रिंग्स का उपयोग करना चाहिए।
मैंने उपयोग करना समाप्त कर दिया
cookie_value = encodeURIComponent(my_string);
तथा
my_string = decodeURIComponent(cookie_value);
यह सभी प्रकार के पात्रों के लिए काम करने लगता है। मेरे पास अजीब मुद्दे थे अन्यथा, यहां तक कि उन पात्रों के साथ भी जो अर्धविराम या अल्पविराम नहीं थे।
;
चरित्र तब तक हो सकता है जब तक वह दोहरे उद्धरणों से घिरा हो? जैसे:Set-Cookie: Name=Va";"lue; Max-Age=3600