TypeScript में `Cookie`

यह लेख TypeScript में Cookie की व्याख्या करता है।

हम ब्राउज़र और सर्वर दोनों पर कुकीज़ को सुरक्षित और विश्वसनीय तरीके से संभालने के व्यावहारिक पैटर्न देखते हैं।

YouTube Video

TypeScript में Cookie

कुकीज़ की बुनियादी अवधारणाएँ

कुकी क्लाइंट पर छोटे स्ट्रिंग्स (name=value जोड़े) संग्रहीत करने का एक तंत्र है, जिसे Set-Cookie HTTP हेडर या document.cookie के माध्यम से बनाया जाता है। आप उनके व्यवहार को सुरक्षा गुणों (HttpOnly, Secure, SameSite आदि) से नियंत्रित कर सकते हैं।

ब्राउज़र में बुनियादी क्रियाएँ: document.cookie

नीचे ब्राउज़र में कुकी लिखने का न्यूनतम उदाहरण है। document.cookie में एक स्ट्रिंग जोड़कर कुकी बनाएँ।

 1// Set a simple cookie that expires in 7 days.
 2// Note: Comments are in English per the user's preference.
 3const setSimpleCookie = (name: string, value: string) => {
 4  const days = 7;
 5  const expires = new Date(Date.now() + days * 86400_000).toUTCString();
 6  // name=value; Expires=...; Path=/
 7  document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}; Expires=${expires}; Path=/`;
 8};
 9
10setSimpleCookie('theme', 'dark');
  • यह कोड 7 दिनों में समाप्त होने वाली कुकी बनाता है। ब्राउज़र पक्ष पर इसका उपयोग आसान है, लेकिन आप HttpOnly सेट नहीं कर सकते, इसलिए संवेदनशील जानकारी को संग्रहीत करने से बचना चाहिए।

कुकी पढ़ना (ब्राउज़र)

निम्नलिखित फ़ंक्शन एक हेल्पर है जो document.cookie से निर्दिष्ट नाम वाली कुकी का मान प्राप्त करता है। document.cookie एक स्ट्रिंग के रूप में लौटाया जाता है, जो सेमीकोलन और स्पेस ('; ') से विभाजित होती है। अतः हम इसे विभाजित करते हैं और इच्छित कुकी को खोजते हैं।

 1// Parse document.cookie and return value for given name or null if not found.
 2const getCookie = (name: string): string | null => {
 3  const cookies = document.cookie ? document.cookie.split('; ') : [];
 4  for (const cookie of cookies) {
 5    const [k, ...rest] = cookie.split('=');
 6    const v = rest.join('=');
 7    if (decodeURIComponent(k) === name) {
 8      return decodeURIComponent(v);
 9    }
10  }
11  return null;
12};
13
14// Example usage:
15const theme = getCookie('theme'); // => "dark" if set
16console.log('theme cookie:', theme);
  • यह फ़ंक्शन सुरक्षित रूप से तुलना और प्राप्त करने के लिए कुकी के नाम और मान दोनों को डिकोड करता है। यह डुप्लिकेट कुकी नामों और एनकोड किए गए विशेष अक्षरों को संभालता है, जिससे यह एक सरल लेकिन मजबूत कार्यान्वयन बनता है।

सुरक्षित गुणों को समझना और लागू करना

कुकीज़ के कई महत्वपूर्ण गुण होते हैं, जिनमें से हर एक सुरक्षा और व्यवहार के दायरे को नियंत्रित करता है।

  • HttpOnly गुण JavaScript से कुकी तक पहुँच को रोकता है, जिससे XSS (क्रॉस-साइट स्क्रिप्टिंग) हमलों के प्रभाव को कम करने में मदद मिलती है। ध्यान दें कि आप ब्राउज़र पक्ष से HttpOnly सेट नहीं कर सकते।
  • Secure गुण कुकीज़ को केवल HTTPS के जरिए भेजे जाने तक सीमित करता है, जिससे ईव्सड्रॉपिंग और छेड़छाड़ का जोखिम घटता है।
  • SameSite गुण यह नियंत्रित करता है कि क्रॉस-साइट रिक्वेस्ट के साथ कुकीज़ भेजी जाएँ या नहीं, और CSRF (क्रॉस-साइट रिक्वेस्ट फोर्जरी) हमलों को रोकने में मदद करता है।
  • Path गुण उन रिक्वेस्ट पाथों के दायरे को निर्धारित करता है जिनके लिए कुकी भेजी जाती है, और Domain गुण उस डोमेन को निर्धारित करता है जहाँ कुकी मान्य होती है।
  • Expires या Max-Age गुण सेट करके आप कुकी की समाप्ति को नियंत्रित कर सकते हैं।

ब्राउज़र में SameSite / Secure जोड़ने का उदाहरण (जो संभव है)

क्लाइंट साइड पर HttpOnly सेट नहीं किया जा सकता। नीचे क्लाइंट साइड पर SameSite और Secure जोड़ने का एक उदाहरण दिया गया है। हालाँकि, Secure केवल HTTPS पेजों पर प्रभावी होता है।

 1// Set cookie with SameSite and Secure attributes (Secure only effective over HTTPS).
 2const setCookieWithAttributes = (name: string, value: string) => {
 3  const maxAge = 60 * 60 * 24 * 7; // 7 days in seconds
 4  // Note: HttpOnly cannot be set from JS; set it on server-side when you want to restrict JS access.
 5  document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}; `
 6    + `Max-Age=${maxAge}; `
 7    + `Path=/; `
 8    + `SameSite=Lax; `
 9    + `Secure`;
10};
11
12setCookieWithAttributes('session_hint', 'true');
  • SameSite=Lax सुरक्षित और सामान्य विकल्प है। कड़ी पाबंदियों के लिए SameSite=Strict का उपयोग करें, लेकिन बाहरी साइटों से वैध नेविगेशन काम करना बंद कर सकते हैं।

सर्वर पर कुकी सेट करना (Set-Cookie) (Node / TypeScript)

सर्वर पर आप Set-Cookie हेडर के माध्यम से HttpOnly जोड़ सकते हैं, इसलिए सत्र प्रबंधन आदर्श रूप से सर्वर-साइड पर किया जाना चाहिए। नीचे Node के http मॉड्यूल का उपयोग करते हुए एक उदाहरण है।

 1// A minimal Node HTTP server in TypeScript that sets a secure HttpOnly cookie.
 2// This example uses built-in 'crypto' for a random session id.
 3import http from 'http';
 4import crypto from 'crypto';
 5
 6const server = http.createServer((req, res) => {
 7  if (req.url === '/login') {
 8    const sessionId = crypto.randomBytes(16).toString('hex');
 9    // Set cookie with HttpOnly, Secure, SameSite and Path
10    // Expires is optional — Max-Age preferred for relative lifetimes.
11    res.setHeader('Set-Cookie', `sid=${sessionId}; `
12      + `HttpOnly; `
13      + `Secure; `
14      + `SameSite=Strict; `
15      + `Path=/; `
16      + `Max-Age=3600`
17    );
18    res.writeHead(302, { Location: '/' });
19    res.end();
20    return;
21  }
22
23  res.writeHead(200, { 'Content-Type': 'text/plain' });
24  res.end('Hello\n');
25});
26
27server.listen(3000, () => {
28  console.log('Server running on http://localhost:3000');
29});
  • जब आप सर्वर साइड पर HttpOnly गुण सेट करते हैं, तो कुकी JavaScript से अप्राप्य हो जाती है, जिससे XSS (क्रॉस-साइट स्क्रिप्टिंग) हमलों के लिए उसे चुराना कठिन हो जाता है। इसके अतिरिक्त, Secure गुण जोड़कर ताकि कुकीज़ हमेशा HTTPS के माध्यम से भेजी जाएँ, आप ईव्सड्रॉपिंग और छेड़छाड़ को रोक सकते हैं और संचार सुरक्षा में सुधार कर सकते हैं।

कुकी सीरियलाइज़ेशन/पार्सिंग कार्यान्वयन (एक सर्वर-साइड हेल्पर)

नीचे Set-Cookie हेडर स्ट्रिंग बनाने वाला एक सरल सर्वर-साइड यूटिलिटी दिया गया है।

 1// Cookie serialization helper for server-side use.
 2// Returns a properly formatted Set-Cookie header value.
 3type CookieOptions = {
 4  path?: string;
 5  domain?: string;
 6  maxAge?: number;
 7  expires?: Date;
 8  httpOnly?: boolean;
 9  secure?: boolean;
10  sameSite?: 'Strict' | 'Lax' | 'None';
11};
12
13const serializeCookie = (name: string, value: string, opts: CookieOptions = {}): string => {
14  const parts: string[] = [`${encodeURIComponent(name)}=${encodeURIComponent(value)}`];
15
16  if (opts.maxAge != null) parts.push(`Max-Age=${Math.floor(opts.maxAge)}`);
17  if (opts.expires) parts.push(`Expires=${opts.expires.toUTCString()}`);
18  if (opts.domain) parts.push(`Domain=${opts.domain}`);
19  parts.push(`Path=${opts.path ?? '/'}`);
20  if (opts.httpOnly) parts.push('HttpOnly');
21  if (opts.secure) parts.push('Secure');
22  if (opts.sameSite) parts.push(`SameSite=${opts.sameSite}`);
23
24  return parts.join('; ');
25};
26
27// Example usage:
28const headerValue = serializeCookie('uid', 'abc123', {
29  httpOnly: true,
30  secure: true,
31  sameSite: 'Lax',
32  maxAge: 3600
33});
34console.log(headerValue);
35// => "uid=abc123; Max-Age=3600; Path=/; HttpOnly; Secure; SameSite=Lax"
  • यह यूटिलिटी कस्टम सर्वर पर Set-Cookie बनाने का आधार बनाती है। लाइब्रेरीज़ कई और दुर्लभ तथा जटिल मामलों को संभाल सकती हैं।

हस्ताक्षरों (HMAC) के साथ छेड़छाड़ रोकना

महत्वपूर्ण मानों को सीधे कुकीज़ में संग्रहीत करना खतरनाक है। हम एक विधि प्रस्तुत करते हैं जो सर्वर पर मानों पर हस्ताक्षर करती है ताकि छेड़छाड़ का पता चल सके। यहाँ हम HMAC-SHA256 का उपयोग करते हैं। उत्पादन वातावरण में, आपको सर्वर-पक्ष पर टोकन रद्दीकरण का प्रबंधन भी करना होगा।

 1// A simple HMAC signing and verification helper for cookies.
 2// Signing prevents client from tampering cookie values.
 3import crypto from 'crypto';
 4
 5const SECRET = 'replace_with_env_secret'; // store in env var in production
 6
 7const signValue = (value: string) => {
 8  const hmac = crypto.createHmac('sha256', SECRET);
 9  hmac.update(value);
10  return `${value}.${hmac.digest('hex')}`;
11};
12
13const verifySignedValue = (signed: string): string | null => {
14  const idx = signed.lastIndexOf('.');
15  if (idx === -1) return null;
16  const value = signed.slice(0, idx);
17  const sig = signed.slice(idx + 1);
18
19  const hmac = crypto.createHmac('sha256', SECRET);
20  hmac.update(value);
21  const expected = hmac.digest('hex');
22  // use timing-safe comparison in production
23  if (crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
24    return value;
25  }
26  return null;
27};
28
29// Example usage:
30const signed = signValue('userId=42');
31console.log('signed:', signed);
32console.log('verified:', verifySignedValue(signed)); // => "userId=42"
  • इस विधि से आप जांच सकते हैं कि कुकी के मान में छेड़छाड़ हुई है या नहीं। साइनिंग कुंजी को स्रोत कोड में शामिल न करें; इसे पर्यावरण चर जैसे सुरक्षित माध्यमों के जरिए प्रबंधित करें।

कुकीज़ और CSRF शमन (सामान्य पैटर्न)

कुकीज़ उपयोग करने वाले सत्रों को CSRF सुरक्षा की आवश्यकता होती है। सामान्य शमन उपायों में शामिल हैं:।

  • अनावश्यक क्रॉस-साइट भेजने को रोकने के लिए SameSite को Lax या Strict पर सेट करें। क्रॉस-ओरिजिन संचार आवश्यक होने पर ही SameSite=None; Secure का उपयोग करें।
  • फॉर्म और API अनुरोधों के लिए सर्वर द्वारा सत्यापित CSRF टोकन का उपयोग करें। टोकन को HttpOnly कुकी में संग्रहीत न करें; इसके बजाय, इसे रेस्पॉन्स बॉडी या मेटा टैग्स के माध्यम से उपलब्ध कराएं, और JavaScript को इसे केवल आवश्यकता होने पर ही पढ़ने दें
  • यदि टोकन JavaScript से एक्सेस किया जा सकता है, तो XSS सुरक्षा (CSP, आउटपुट एस्केपिंग, आदि) भी लागू करना सुनिश्चित करें।
  • संवेदनशील कार्रवाइयों और लॉगिन पर पुन: प्रमाणीकरण आवश्यक करें, और सत्र फिक्सेशन हमलों को रोकें।

नीचे एक सुरक्षित क्लाइंट का उदाहरण है जो हेडर में CSRF टोकन भेजता है। यह मानता है कि क्लाइंट सर्वर से पहले ही टोकन प्राप्त कर चुका है, जैसे कि रेस्पॉन्स बॉडी में।

 1// Example of sending CSRF token safely in a header using fetch.
 2// Assumes CSRF token was provided securely (e.g., via response body or meta tag).
 3async function sendProtectedRequest(url: string, csrfToken: string) {
 4  const res = await fetch(url, {
 5    method: 'POST',
 6    credentials: 'same-origin', // include cookies for same-site requests
 7    headers: {
 8      'Content-Type': 'application/json',
 9      'X-CSRF-Token': csrfToken
10    },
11    body: JSON.stringify({ action: 'doSomething' })
12  });
13  return res;
14}
  • यदि आप credentials: 'same-origin' निर्दिष्ट करते हैं, तो केवल उसी ओरिजिन की कुकीज़ भेजी जाती हैं। सर्वर पर, X-CSRF-Token हेडर के मान को मान्य करें और यह सत्यापित करें कि टोकन मेल खाता है। यदि क्रॉस-साइट अनुरोध आवश्यक हैं, तो CORS को सावधानीपूर्वक कॉन्फ़िगर करें।

क्रॉस-साइट (CORS) और credentials के साथ संबंध

क्रॉस-ओरिजिन संचार में कुकी भेजने और प्राप्त करने के लिए, क्लाइंट को credentials: 'include' निर्दिष्ट करना होगा और सर्वर को Access-Control-Allow-Credentials: true सेट करना होगा। हालाँकि, इस कॉन्फ़िगरेशन को केवल विश्वसनीय ओरिजिन तक सीमित रखें और Access-Control-Allow-Origin: * का उपयोग न करें।

 1async function fetchCrossOriginData() {
 2  // Example: cross-origin fetch sending cookies.
 3  // Server must set Access-Control-Allow-Credentials: true
 4  // and a specific trusted origin.
 5  const res = await fetch('https://api.example.com/data', {
 6    credentials: 'include', // send cookies only to trusted domains
 7    method: 'GET'
 8  });
 9  return res;
10}
  • CORS और कुकीज़ का संयोजन सुरक्षा के दृष्टिकोण से बहुत नाज़ुक है। अनुमत ओरिजिन को एक व्हाइटलिस्ट के साथ कड़ाई से प्रबंधित करें और अनावश्यक क्रॉस-साइट संचार से बचें। साथ ही, SameSite=None; Secure का उपयोग करते समय मैन-इन-द-मिडल हमलों को रोकने के लिए HTTPS अनिवार्य करें।

उदाहरण: Express (TypeScript) के साथ सुरक्षित सेशन कुकी सेटिंग्स

व्यवहार में, Express, cookie लाइब्रेरी, express-session आदि का उपयोग करें। नीचे express और cookie-parser का उपयोग करते हुए एक सरल उदाहरण है। व्यवहार में, secure को true पर सेट करें और secret को पर्यावरण चर के माध्यम से प्रबंधित करें।

 1// Express example using cookie-parser and setting a secure httpOnly cookie.
 2// npm install express cookie-parser @types/express @types/cookie-parser
 3import express from 'express';
 4import cookieParser from 'cookie-parser';
 5
 6const app = express();
 7app.use(cookieParser(process.env.COOKIE_SECRET));
 8
 9app.post('/login', (req, res) => {
10  // authenticate user (omitted)
11  const sessionId = 'generated-session-id';
12  res.cookie('sid', sessionId, {
13    httpOnly: true,
14    secure: true,        // require HTTPS in production
15    sameSite: 'lax',
16    maxAge: 1000 * 60 * 60 // 1 hour
17  });
18  res.json({ ok: true });
19});
20
21app.listen(3000);
  • cookieParser की secret विशेषता का उपयोग करके, आप साइन की गई कुकीज़ के साथ आसानी से काम कर सकते हैं। हालाँकि, वास्तविक अनुप्रयोगों में, सुरक्षा और स्केलेबिलिटी के दृष्टिकोण से, आपको डेटा को सीधे कुकीज़ में संग्रहीत नहीं करना चाहिए; इसके बजाय, एक समर्पित सत्र स्टोर का उपयोग करें।

कुकी उपसर्ग __Host- और __Secure-

कुछ उपसर्गों के लिए ब्राउज़र विशेष नियम लागू करते हैं।

  • __Secure- उपसर्ग यदि कुकी का नाम __Secure- से शुरू होता है, तो Secure गुण आवश्यक है।
  • __Host- उपसर्ग यदि यह __Host- से शुरू होता है, तो Secure आवश्यक है, पथ / (रूट) होना चाहिए, और Domain सेट नहीं होना चाहिए।

इनका उपयोग गलत कॉन्फ़िगरेशन को कम करता है और सुरक्षा में सुधार करता है।

कुकी सर्वोत्तम प्रथाएँ

कुकीज़ को सुरक्षित रूप से संभालने के लिए, निम्नलिखित बिंदुओं पर विचार करें।

  • संवेदनशील जानकारी को सीधे कुकीज़ में संग्रहित न करें। एक्सेस टोकनों के लिए सर्वर-साइड सत्र ID को प्राथमिकता दें।
  • HttpOnly, Secure और SameSite=Lax (या Strict) के साथ सत्र कुकी सेट करें।
  • __Host- और __Secure- जैसे उपसर्गों का लाभ उठाएँ।
  • छेड़छाड़ और जासूसी से बचाव के लिए हस्ताक्षर (HMAC) और एन्क्रिप्शन पर विचार करें।
  • Secure सक्षम करें और HTTPS अनिवार्य करें।
  • न्यूनतम विशेषाधिकार और कम अवधि की समाप्ति का लक्ष्य रखें।
  • CSRF टोकन का उपयोग करें।
  • ब्राउज़रों में SameSite व्यवहार के अंतर से सावधान रहें, विशेषकर पुराने ब्राउज़रों में।

कुकीज़ के बारे में सामान्य गलतफहमियाँ

कुकीज़ के संबंध में, निम्नलिखित सामान्य भ्रांतियों पर ध्यान दें।

  • 'HttpOnly जोड़ने से XSS का प्रभाव समाप्त हो जाता है।' HttpOnly JavaScript द्वारा कुकीज़ की पहुँच रोकता है, लेकिन XSS का उपयोग अभी भी मनचाही रिक्वेस्ट भेजने के लिए किया जा सकता है। आपको CSRF टोकन सत्यापन, CSP (Content Security Policy), और इनपुट सैनिटाइजेशन भी अपनाना चाहिए।
  • 'लोकल डेवलपमेंट के लिए Secure अनावश्यक है।' लोकल वातावरण में भी HTTPS का सिमुलेशन करना और व्यवहार की पुष्टि करना टेस्ट की सटीकता बढ़ाता है। कम से कम, स्टेजिंग और प्रोडक्शन वातावरण में HTTPS का उपयोग किया जाना चाहिए।
  • 'लंबी समाप्ति अवधि सुविधाजनक होती है।' यदि आप कुकी की आयु लंबी रखते हैं, तो चोरी होने पर उनके दुरुपयोग की संभावित अवधि बढ़ जाती है। आप छोटी समाप्ति अवधि निर्धारित कर सकते हैं और आवधिक पुन:प्रमाणीकरण व टोकन रोटेशन शामिल कर सकते हैं।

सारांश

कुकीज़ का उपयोग आसान है, लेकिन उनका गलत प्रबंधन सुरक्षा कमजोरियाँ पैदा कर सकता है। उन्हें TypeScript के साथ सही तरीके से प्रबंधित करने के लिए HttpOnly, Secure और SameSite जैसे गुणों को समझना और सुरक्षित सर्वर-साइड सेटिंग्स लागू करना महत्वपूर्ण है। संवेदनशील डेटा को सीधे संग्रहीत न करके और हस्ताक्षरों को कम अवधि की समाप्ति के साथ संयोजित करके, आप सुरक्षित और विश्वसनीय सत्र प्रबंधन प्राप्त कर सकते हैं।

आप हमारे YouTube चैनल पर Visual Studio Code का उपयोग करके ऊपर दिए गए लेख के साथ आगे बढ़ सकते हैं। कृपया YouTube चैनल को भी देखें।

YouTube Video