Brauzerda ma'lumot saqlash

Cookie

Cookie'lar โ€” brauzer tomonidan saqlanadigan kichik matnli ma'lumot bo'laklaridir. Ular HTTP protokolining bir qismi bo'lib, aksar hollarda foydalanuvchini tanib olish (autentifikatsiya) uchun ishlatiladi. Cookie odatda server tomonidan Set-Cookie sarlavhasi orqali o'rnatiladi, keyin brauzer har bir so'rovda ularni Cookie sarlavhasida serverga qaytaradi.

Cookie nima va qanday ishlaydi

Cookie nom=qiymat ko'rinishidagi juftlik bo'lib, brauzerda saqlanadi. U ma'lum bir domenga bog'langan holda saqlanadi va o'sha domenga yuborilgan har bir HTTP so'rovda avtomatik ravishda serverga qaytariladi. Aynan shu avtomatik qaytish xususiyati cookie'ni sessiyalarni saqlash uchun qulay qiladi.

Odatiy senariy quyidagicha: foydalanuvchi tizimga kiradi, server autentifikatsiya sessiya identifikatorini Set-Cookie sarlavhasi bilan o'rnatadi, keyin brauzer har bir so'rovda o'sha sessiya cookie'sini yuboradi va server foydalanuvchini tanib oladi.

Cookie'lar brauzerga xos mexanizmdir. Ularni faqat brauzer muhitida ishlaydigan JavaScript koddan o'qish/yozish mumkin. Node.js yoki playground muhitida document obyekti bo'lmaydi, shu sabab quyidagi misollarni faqat brauzer konsolida sinab ko'ring.

document.cookie orqali o'qish

Brauzer JavaScript koddan cookie'ga document.cookie xususiyati orqali kirish mumkin. Uni o'qishimiz barcha cookie'larni bitta satr ko'rinishida beradi, bunda juftliklar ; (nuqta-vergul va probel) bilan ajratiladi:

// Brauzerda:
let all = document.cookie;
console.log(all);
// masalan: "user=Ali; theme=dark; sessionId=abc123"

Ko'rib turganingizdek, document.cookie โ€” bu oddiy obyekt emas, balki maxsus formatdagi satr. Bitta cookie qiymatini olish uchun satrni ajratib olishimiz kerak. Quyida ma'lum nom bo'yicha qiymatni topuvchi funksiya:

function getCookie(name) {
  let matches = document.cookie.match(new RegExp(
    '(?:^|; )' + name.replace(/([.$?*|{}()\[\]\\/+^])/g, '\\$1') + '=([^;]*)'
  ));
  return matches ? decodeURIComponent(matches[1]) : undefined;
}

// ishlatish:
let user = getCookie('user');
console.log(user); // "Ali" (agar mavjud bo'lsa)
Cookie nomi va qiymatida maxsus belgilar (probel, ;, kirill harflar va h.k.) bo'lishi mumkin emas. Shu sabab qiymatni yozishda encodeURIComponent, o'qishda esa decodeURIComponent ishlatiladi.

document.cookie orqali yozish

document.cookiega yozish alohida xususiyatga ega: u o'zgartiruvchi (writable) bo'lsa-da, unga qiymat berish barcha cookie'larni almashtirmaydi, balki faqat siz ko'rsatgan bitta cookie'ni o'rnatadi yoki yangilaydi:

// Brauzerda:
document.cookie = 'user=Ali';
// endi document.cookie ichida user=Ali paydo bo'ladi,
// boshqa cookie'lar o'chib ketmaydi

Qiymatda maxsus belgilar bo'lsa, uni kodlash shart:

let name = 'user';
let value = 'Ali Valiyev'; // probel bor
document.cookie = name + '=' + encodeURIComponent(value);
document.cookie = ... texnik jihatdan xususiyat bo'lsa ham, u maxsus aksessor (accessor) sifatida ishlaydi. Har bir yozish faqat bitta cookie'ni ta'sirlaydi โ€” bu odatiy obyekt xususiyatidan farqli xatti-harakat. Butun ro'yxatni bir marta yozib bo'lmaydi.

path โ€” cookie'ning yo'l ko'lami

path=/... parametri cookie ko'rinadigan URL yo'lini belgilaydi. Cookie faqat shu yo'l va uning ostki yo'llari uchun brauzerdan serverga yuboriladi:

document.cookie = 'user=Ali; path=/admin';
// bu cookie faqat /admin, /admin/panel kabi
// yo'llarda serverga yuboriladi, /shop'da yuborilmaydi

Odatda path=/ ishlatiladi โ€” bu cookie'ni butun sayt bo'ylab ko'rinadigan qiladi. Agar path ko'rsatilmasa, u joriy sahifaning yo'liga sozlanadi, bu ko'pincha kutilmagan cheklovlarga olib keladi.

Deyarli har doim path=/ qo'ying โ€” shunda cookie saytning barcha sahifalarida ishlaydi.

domain โ€” cookie qaysi domenda ko'rinadi

domain parametri cookie qaysi domenda serverga yuborilishini belgilaydi. Standart holatda cookie faqat o'zi o'rnatilgan aniq domenda ko'rinadi va subdomen'larda ko'rinmaydi:

// site.com'da o'rnatilgan cookie standart holatda
// forum.site.com'da KO'RINMAYDI
document.cookie = 'user=Ali';

Subdomen'larga ham cookie'ni ulashish uchun asosiy domenni ko'rsatamiz:

// site.com'da:
document.cookie = 'user=Ali; domain=site.com';
// endi cookie forum.site.com, shop.site.com'da ham ko'rinadi
Xavfsizlik sababli cookie'ni begona domenga berib bo'lmaydi. Faqat joriy domen yoki uning yuqori (asosiy) domenini ko'rsatishingiz mumkin. Masalan other.comni site.comdan o'rnatolmaysiz.

expires va max-age โ€” amal qilish muddati

Standart holatda cookie sessiya cookie'si bo'ladi โ€” brauzer yopilganda o'chib ketadi. Cookie'ni uzoqroq saqlash uchun expires yoki max-age ishlatiladi.

expires โ€” aniq sana

expires cookie tugash sanasini GMT formatida (toUTCString()) belgilaydi:

let date = new Date(Date.now() + 86400e3); // +1 kun
date = date.toUTCString();
document.cookie = 'user=Ali; expires=' + date + '; path=/';

O'tmishdagi sanani berish cookie'ni o'chiradi:

// cookie'ni o'chirish:
document.cookie = 'user=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/';

max-age โ€” soniyalardagi muddat

max-age โ€” hozirgi vaqtdan boshlab soniyalarda ifodalangan muddat. U expiresga qulay muqobil:

// 1 soatga:
document.cookie = 'user=Ali; max-age=3600; path=/';

// darhol o'chirish (0 yoki manfiy qiymat):
document.cookie = 'user=Ali; max-age=0; path=/';
max-age=0 yoki manfiy qiymat cookie'ni zudlik bilan o'chiradi. Cookie'ni o'chirishning eng ishonchli yo'li โ€” uni bo'sh qiymat va o'tgan muddat bilan qayta o'rnatish, bunda path va domain asl o'rnatishdagidek bo'lishi kerak.

secure va samesite โ€” xavfsizlik bayroqlari

secure bayrog'i cookie'ni faqat HTTPS ulanishida yuborishga majbur qiladi. Bu cookie'ning shifrlanmagan HTTP orqali oshkor bo'lishining oldini oladi:

// faqat HTTPS orqali yuboriladi:
document.cookie = 'user=Ali; secure; path=/';

samesite bayrog'i โ€” CSRF (cross-site request forgery) hujumlaridan himoya qiluvchi muhim mexanizm. U cookie'ning boshqa saytdan kelgan so'rovlarda yuborilishini boshqaradi:

document.cookie = 'sessionId=abc123; samesite=strict; secure; path=/';
Autentifikatsiya cookie'lari uchun samesite=lax yoki strict va secureni birga qo'llash tavsiya etiladi โ€” bu CSRF hujumlaridan jiddiy himoya beradi.

httpOnly โ€” faqat serverdan

httpOnly bayrog'i โ€” bu JavaScript orqali emas, faqat server tomonidan Set-Cookie sarlavhasida o'rnatiladigan xususiyat. U cookie'ga JavaScript koddan (document.cookie orqali) kirishni butunlay taqiqlaydi:

// Bu server sarlavhasi (JavaScript emas!):
// Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict

// Brauzerda:
console.log(document.cookie);
// httpOnly cookie bu yerda KO'RINMAYDI
httpOnly XSS (cross-site scripting) hujumlariga qarshi muhim himoya. Agar sahifaga zararli skript kirsa ham, u httpOnly cookie'ni o'g'irlay olmaydi, chunki JavaScript uni umuman o'qiy olmaydi. Sessiya token'larini doim httpOnly qilish tavsiya etiladi.

Cookie cheklovlari

Cookie'lar hajm va son jihatidan qattiq cheklangan:

Katta hajmdagi ma'lumotni saqlash uchun cookie mos emas โ€” buning uchun localStorage yoki IndexedDB ancha qulay. Cookie'ning asosiy vazifasi โ€” autentifikatsiya, ya'ni foydalanuvchini serverda tanib olish.

To'liq yordamchi funksiyalar

Amalda cookie bilan ishlashni osonlashtirish uchun uchta funksiya to'plami odatda yetarli: o'qish, yozish (parametrlar bilan) va o'chirish.

// O'qish
function getCookie(name) {
  let matches = document.cookie.match(new RegExp(
    '(?:^|; )' + name.replace(/([.$?*|{}()\[\]\\/+^])/g, '\\$1') + '=([^;]*)'
  ));
  return matches ? decodeURIComponent(matches[1]) : undefined;
}

// Yozish (options bilan)
function setCookie(name, value, options = {}) {
  options = {
    path: '/',
    ...options
  };

  if (options.expires instanceof Date) {
    options.expires = options.expires.toUTCString();
  }

  let updated = encodeURIComponent(name) + '=' + encodeURIComponent(value);

  for (let key in options) {
    updated += '; ' + key;
    let val = options[key];
    if (val !== true) {
      updated += '=' + val;
    }
  }

  document.cookie = updated;
}

// O'chirish
function deleteCookie(name) {
  setCookie(name, '', { 'max-age': -1 });
}
// ishlatish:
setCookie('user', 'Ali', { 'max-age': 3600, samesite: 'strict' });
console.log(getCookie('user')); // "Ali"
deleteCookie('user');
Cookie'ni o'chirishda o'sha path va domainni ko'rsatish muhim โ€” aks holda brauzer boshqa cookie'ni nazarda tutayapti deb hisoblab, o'chirmasligi mumkin.

Xulosa