Session va Token-based auth farqi
Oldingi darsda HTTP holatsiz ekanini aytgan edik. Login’dan keyin server klientga maxsus belgi beradi, klient esa uni har bir so‘rovda qaytarib yuboradi. Bu belgini tashkil qilishning ikki asosiy usuli bor: session va token.
Ikki xil mehmonxonani tasavvur qiling.
Birinchisida qabulxona sizga faqat raqamli kalit beradi, masalan 305. Kim qaysi xonada yashashi, qachon kelgani va qachon ketishi qabulxona daftarida yozilgan. Kalit yo‘qolsa, qabulxona uni daftardan o‘chirib qo‘yadi va kalit darhol ishlamay qoladi. Bu — session.
Ikkinchisida sizga muhrlangan guvohnoma beriladi: "Ali Valiyev, 305-xona, 5-oktabrgacha. Direktor imzosi". Qo‘riqchi daftarga qaramaydi. U faqat imzo haqiqiy va muddat tugamaganini tekshiradi. Bu — token.
Session asosidagi autentifikatsiya
1. POST /login {email, password}
Server: parol to‘g‘ri
Server: session yaratadi → sessions["f3a9..."] = {user_id: 42, expires: ...}
← Set-Cookie: session_id=f3a9...; HttpOnly; Secure; SameSite=Lax
2. GET /me
Cookie: session_id=f3a9...
Server: sessions["f3a9..."] → user_id 42
← 200 {"id": 42, ...}
3. POST /logout
Server: delete(sessions, "f3a9...")
Session ID — hech qanday ma’noga ega bo‘lmagan uzun tasodifiy satr. Barcha ma’lumot serverda saqlanadi: xotirada, Redis’da yoki bazada. Klient faqat "kalit raqami"ni saqlaydi.
Go’da oddiy session
curl -c cookies.txt -X POST http://localhost:8080/login
curl -b cookies.txt http://localhost:8080/me
curl -b cookies.txt -X POST http://localhost:8080/logout
curl -b cookies.txt http://localhost:8080/me
curl -c cookie’ni faylga saqlaydi, -b esa fayldan o‘qib yuboradi. Brauzer buni avtomatik bajaradi.
Info
Cookie’da Secure: true o‘rnatilgan, ya’ni brauzer uni faqat HTTPS orqali yuboradi. curl va zamonaviy brauzerlar localhost uchun istisno qiladi. Shuning uchun misol lokal kompyuterda HTTP orqali ham ishlaydi.
Session ID qanday bo‘lishi kerak?
- Tasodifiy va uzun.
crypto/randbilan kamida 128 bit, misolda esa 256 bit.math/randyoki ketma-ket raqamlar ishlatilmaydi, aks holda ularni taxmin qilish mumkin. - Ma’nosiz. ID ichida foydalanuvchi ID’si yoki email bo‘lmaydi.
- Login’dan keyin yangilanadi. Login’dan oldin berilgan ID’ni qayta ishlatish session fixation hujumiga yo‘l ochadi.
Cookie parametrlari
| Parametr | Ma’nosi | Nima uchun kerak |
|---|---|---|
HttpOnly |
JavaScript cookie’ni o‘qiy olmaydi | XSS orqali cookie o‘g‘irlanishining oldini oladi |
Secure |
Faqat HTTPS orqali yuboriladi | Tarmoqda ushlab olinishining oldini oladi |
SameSite=Lax |
Boshqa saytdan kelgan POST so‘rovlarga cookie qo‘shilmaydi |
CSRF hujumlaridan himoyalaydi |
SameSite=Strict |
Boshqa saytdan kelgan har qanday so‘rovga qo‘shilmaydi | Kuchliroq himoya, lekin tashqi havolalardan kelganda foydalanuvchi "tizimdan chiqqan" bo‘lib ko‘rinadi |
Path=/ |
Butun saytga tegishli | |
MaxAge |
Necha soniya yashaydi | -1 — darhol o‘chirish |
Token asosidagi autentifikatsiya
1. POST /login {email, password}
Server: parol to‘g‘ri
Server: token yaratadi va imzolaydi → {"sub": 42, "exp": ...} + imzo
← 200 {"access_token": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOjQyfQ.x7k..."}
2. GET /me
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOjQyfQ.x7k...
Server: imzoni tekshiradi → to‘g‘ri, sub = 42
← 200 {"id": 42, ...}
Token ichida foydalanuvchi haqidagi ma’lumot bor: kim ekani, muddati qachon tugashi. Server hech narsani saqlamaydi. U faqat tokenni o‘zi imzolaganini tekshiradi. Imzoni faqat maxfiy kalitni biladigan server yarata oladi. Shuning uchun token soxtalashtirilsa, bu darhol aniqlanadi.
Eng keng tarqalgan token formati — JWT (JSON Web Token). Uning tuzilishi JWT yaratish va tekshirish darsida ko‘riladi.
Solishtirish
| Mezon | Session | Token (JWT) |
|---|---|---|
| Ma’lumot qayerda | Serverda | Tokenning o‘zida |
| Har bir so‘rovda | Omborga (Redis, baza) murojaat | Faqat imzo tekshiriladi |
| Masshtablash | Barcha server nusxalari umumiy omborga ulanadi | Har bir nusxa mustaqil tekshiradi |
| Chiqish (logout) | Session o‘chiriladi, darhol ishlamay qoladi | Token muddati tugaguncha ishlaydi |
| Bloklash | Barcha session’larni o‘chirish kifoya | Qo‘shimcha mexanizm kerak |
| Hajmi | ~40 bayt | Bir necha yuz bayt |
| Mobil ilova va serverlararo | Mumkin, lekin noqulay | Qulay |
| Brauzer | Cookie orqali tabiiy ishlaydi | Saqlash joyini tanlash kerak |
Tokenning asosiy muammosi: bekor qilish
Foydalanuvchi "tizimdan chiqish" tugmasini bosdi yoki telefoni o‘g‘irlandi. Session bo‘lsa, uni serverda o‘chirish kifoya. JWT esa muddati tugaguncha haqiqiy qoladi, chunki server uni hech qayerda saqlamaydi.
Bu muammo odatda ikki usul bilan hal qilinadi:
1. Qisqa muddatli access token va uzoq muddatli refresh token.
access_token → 15 daqiqa, har bir so‘rovda yuboriladi
refresh_token → 30 kun, faqat POST /auth/refresh uchun, serverda saqlanadi
Access token o‘g‘irlansa, u ko‘pi bilan 15 daqiqa ishlaydi. Refresh token esa serverda saqlanadi, shu sababli uni istalgan paytda bekor qilish mumkin. Access token muddati tugaganda klient refresh token bilan yangisini oladi.
Refresh token amalda session’ga o‘xshaydi. Ya’ni bu usul ikkala yondashuvning afzalliklarini birlashtiradi: tez-tez bo‘ladigan so‘rovlar omborga murojaat qilmaydi, lekin sessiyani bekor qilish imkoni ham saqlanadi.
2. Qora ro‘yxat (denylist). Bekor qilingan tokenlarning ID’lari (jti) muddati tugaguncha Redis’da saqlanadi. Har bir so‘rovda token shu ro‘yxatda yo‘qligi tekshiriladi. Bu holatda token holatsizlik afzalligini qisman yo‘qotadi.
Brauzerda tokenni qayerda saqlash kerak?
| Joy | XSS xavfi | CSRF xavfi |
|---|---|---|
localStorage |
⚠️ Istalgan JavaScript o‘qiy oladi | Yo‘q |
| JavaScript xotirasi (o‘zgaruvchi) | Kamroq, sahifa yangilansa yo‘qoladi | Yo‘q |
HttpOnly cookie |
JavaScript o‘qiy olmaydi | ⚠️ SameSite va CSRF himoyasi kerak |
Aniq bir "to‘g‘ri" javob yo‘q. Ko‘p hollarda qo‘llaniladigan kelishuv:
- Brauzer ilovasi (SPA) va API bitta domenda bo‘lsa —
HttpOnly,Secure,SameSitecookie. Bu amalda session yondashuviga yaqin. - Mobil ilova yoki boshqa server —
Authorization: Bearersarlavhasi. Token qurilmaning xavfsiz omborida saqlanadi: iOS Keychain yoki Android Keystore.
Qaysi birini tanlash kerak?
Session tanlang, agar:
- asosiy klient brauzer va API bitta domenda bo‘lsa;
- foydalanuvchini darhol tizimdan chiqarish imkoni muhim bo‘lsa, masalan bank yoki admin panelda;
- sizda allaqachon Redis yoki boshqa umumiy ombor bo‘lsa.
Token tanlang, agar:
- klientlar mobil ilovalar, boshqa servislar yoki uchinchi tomon dasturlari bo‘lsa;
- bir nechta mustaqil servis foydalanuvchini umumiy ombor bo‘lmagan holda tanishi kerak bo‘lsa;
- mikroservislar orasida foydalanuvchi ma’lumotini uzatish kerak bo‘lsa.
Bu kursda token yondashuvini o‘rganamiz. Chunki u API’lar orasida keng tarqalgan va unda ichki jarayonlarni tushunish uchun ko‘proq narsa bor. Keyingi darslardagi auth middleware va ruxsat tekshiruvi mantiqi esa session bilan ham deyarli o‘zgarmaydi.
Xulosa
- Session’da ma’lumot serverda, klientda faqat tasodifiy ID bo‘ladi. Uni darhol bekor qilish oson.
- Token’da ma’lumot tokenning o‘zida, server faqat imzoni tekshiradi. U masshtablash uchun qulay, lekin bekor qilish qiyinroq.
- Cookie uchun
HttpOnly,SecurevaSameSiteparametrlari majburiy. - Tokenni bekor qilish muammosi qisqa muddatli access token va serverda saqlanadigan refresh token orqali hal qilinadi.
- Tanlov klient turiga va xavfsizlik talablariga bog‘liq.
Keyingi darsda ro‘yxatdan o‘tish va login endpointlarini yozamiz.