Veb
JWT va token xatolari: imzo, muddat, saqlash va bekor qilish
Token bilan ishlaydigan API'larda ekspertiza imzo algoritmi, kalit kuchi, muddat va logout'dan keyingi holatni tekshiradi. Keng tarqalgan xatolar va Laravel, Node, Flutter'da tuzatish.
· 10 daq. o'qish

Mobil ilova yoki SPA serverga har bir so'rovda "men kimman" degan dalilni yuborishi kerak. Ko'pincha bu dalil — token: JWT (JSON Web Token) yoki serverda saqlanadigan tasodifiy satr. Token qulay, lekin u aslida kalit: kimning qo'lida bo'lsa, o'sha foydalanuvchi nomidan ish ko'radi. Shuning uchun token qanday yaratilishi, tekshirilishi, saqlanishi va bekor qilinishi xavfsizlikning markaziy qismidir.
Bu maqolada JWT va boshqa tokenlar bilan bog'liq keng tarqalgan xatolarni, ularni o'zingiz qanday tekshirishni va Laravel (Sanctum, Passport), Node va Flutter'da qanday tuzatishni ko'rib chiqamiz.
JWT qisqacha
JWT uch qismdan iborat, nuqta bilan ajratilgan: header.payload.signature. Header va payload — oddiy Base64URL bilan kodlangan JSON, ya'ni shifrlanmagan. Ularni har kim o'qiy oladi:
echo 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9' | base64 -d
# {"alg":"HS256","typ":"JWT"}
Imzo esa token o'zgartirilmaganini kafolatlaydi. HS256 da imzo umumiy maxfiy kalit (secret) bilan, RS256 yoki ES256 da esa yopiq kalit bilan qo'yiladi va ochiq kalit bilan tekshiriladi.
Birinchi xulosa: payload'ga maxfiy ma'lumot (parol, pasport raqami, ichki ID'lar ro'yxati) yozmang. Token mobil qurilmada, brauzerda va loglarda qoladi.
Nima uchun bu ekspertiza uchun muhim
Ekspertizada mutaxassis tokenni ushlab oladi va bir nechta savolga javob qidiradi: imzoni chetlab o'tish mumkinmi, kalitni topish mumkinmi, token qancha yashaydi, logout'dan keyin ishlaydimi, token qayerda saqlanadi? Mobil ilova tekshiruvida esa tokenning qurilmada shifrlanmagan holda saqlanishi alohida topilma sifatida yoziladi — o'z ilovamiz ekspertizasida "maxfiy ma'lumotlar ichki xotirada shifrlanmagan saqlanadi" degan yuqori darajali topilma aynan shu sinfdan edi.
Xato 1: alg: none va algoritm almashtirish
JWT standartida none algoritmi bor — imzosiz token. Ba'zi eski yoki noto'g'ri sozlangan kutubxonalar header'dagi alg qiymatiga ishonadi: hujumchi "alg":"none" yozib, imzoni olib tashlasa, token qabul qilinadi.
Ikkinchi variant — algoritm chalkashligi (algorithm confusion). Server RS256 ishlatadi, lekin tekshirish funksiyasi algoritmni tokendan oladi. Hujumchi alg ni HS256 ga almashtiradi va tokenni serverning ochiq kaliti bilan HMAC orqali imzolaydi. Kutubxona ochiq kalitni HMAC secret sifatida ishlatsa, soxta token haqiqiy bo'lib chiqadi.
Yechim bitta: ruxsat etilgan algoritmni serverda qat'iy belgilang, tokendagi alg ga ishonmang.
// Node, jsonwebtoken
const payload = jwt.verify(token, publicKey, {
algorithms: ['RS256'],
issuer: 'https://api.your-domain.uz',
audience: 'mobile-app',
});
PHP'da firebase/php-jwt ning zamonaviy versiyalari kalitni algoritm bilan birga talab qiladi:
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
$decoded = JWT::decode($token, new Key($publicKey, 'RS256'));
Tekshirish: o'z test tokeningizni oling, header'ni {"alg":"none","typ":"JWT"} ga almashtiring, payload'dagi foydalanuvchi ID'sini o'zgartiring, imzo qismini bo'sh qoldiring (header.payload.) va API'ga yuboring. Javob 401 bo'lishi kerak.
Xato 2: zaif secret
HS256 tokenni imzolash uchun ishlatilgan secret qisqa yoki taxmin qilinadigan bo'lsa (secret, 123456, loyiha nomi, hujjatdagi namunaviy qiymat), bitta haqiqiy token yordamida uni oflayn tanlab topish mumkin. Buning uchun hashcat kabi umumiy vositalar bor va bunda server hech narsani sezmaydi. Kalit topilsa, hujumchi istalgan foydalanuvchi, jumladan admin nomidan token yasay oladi.
Tuzatish:
- Secret kamida 256 bit tasodifiy bo'lsin:
openssl rand -base64 48. - U kodda yoki repozitoriyda emas, muhit o'zgaruvchisi yoki sirlar omborida turadi — sirlarni boshqarish haqidagi maqolaga qarang.
- Bir nechta xizmat tokenni tekshirishi kerak bo'lsa, asimmetrik algoritm (
RS256,ES256) ishlating: tekshiruvchilarga faqat ochiq kalit beriladi. - Kalit sizib chiqqan bo'lsa yoki shubha bo'lsa — almashtiring. Bu barcha tokenlarni bekor qiladi, shuning uchun almashtirish jarayonini oldindan rejalashtiring.
Xato 3: muddatsiz tokenlar
exp maydoni bo'lmagan JWT yoki muddat qo'yilmagan API tokeni abadiy ishlaydi. Telefon yo'qolsa, token logga tushib qolsa yoki xodim ishdan ketsa ham, u ishlashda davom etadi.
Amaliy yondashuv: qisqa umrli access token (masalan, 15 daqiqadan 1 soatgacha) va uzoqroq umrli, lekin boshqariladigan refresh token. Muddatlarni biznes talabiga qarab tanlang; muhimi — chegara bo'lsin va server uni tekshirsin. Tekshirishda exp bilan birga iss (kim chiqargan) va aud (kim uchun) maydonlarini ham solishtiring.
Xato 4: tokenni noto'g'ri joyda saqlash
Brauzerda. localStorage va sessionStorage ga sahifadagi har qanday JavaScript kira oladi. Saytda bitta XSS bo'lsa, token o'g'irlanadi. Iloji bo'lsa, brauzer ilovasi uchun tokenni HttpOnly, Secure, SameSite atributli cookie'da saqlang — JavaScript uni o'qiy olmaydi. Bunda CSRF himoyasini ham unutmang.
Mobil ilovada. Tokenni SharedPreferences, NSUserDefaults yoki oddiy faylda saqlash — ekspertizada tez-tez uchraydigan topilma. To'g'ri joy — Android Keystore va iOS Keychain. Flutter'da:
const storage = FlutterSecureStorage(
aOptions: AndroidOptions(encryptedSharedPreferences: true),
);
await storage.write(key: 'access_token', value: token);
// logout
await storage.deleteAll();
Batafsil: Keystore va Keychain.
Loglarda. Authorization headeri yoki URL'dagi ?token= access loglarga tushadi. Tokenni query string'da yubormang va loglarda headerlarni maskalang.
Xato 5: refresh token aylantirilmaydi
Refresh token uzoq yashaydi, shuning uchun u eng qimmatli nishon. Agar u har safar bir xil qolsa, o'g'irlangan nusxa egasi bilan parallel ravishda cheksiz ishlaydi.
To'g'ri sxema — rotation: har bir yangilashda eski refresh token bekor qilinadi va yangisi beriladi. Allaqachon ishlatilgan refresh token qayta kelsa, bu o'g'irlik belgisi: shu zanjirdagi barcha tokenlarni bekor qiling va foydalanuvchidan qayta kirishni so'rang.
async function refresh(oldToken) {
const record = await db.refreshToken.findUnique({ where: { hash: sha256(oldToken) } });
if (!record || record.expiresAt < new Date()) throw new Unauthorized();
if (record.usedAt) {
await db.refreshToken.updateMany({ where: { familyId: record.familyId }, data: { revoked: true } });
throw new Unauthorized();
}
await db.refreshToken.update({ where: { id: record.id }, data: { usedAt: new Date() } });
return issueTokens(record.userId, record.familyId);
}
E'tibor bering: bazada refresh tokenning o'zi emas, uning xeshi saqlanadi.
Xato 6: logout tokenni bekor qilmaydi
JWT o'z-o'zidan to'liq (stateless): server uni bazaga qaramasdan tekshiradi. Shuning uchun "logout" ko'pincha faqat ilovadan tokenni o'chiradi, serverda esa token muddati tugaguncha ishlayveradi. Ekspertizada buni oddiy usulda tekshirishadi: logout'dan oldin olingan token bilan logout'dan keyin so'rov yuboriladi.
Variantlar:
- Access token muddatini qisqa qiling va logout'da refresh tokenni serverda bekor qiling.
- Payload'ga
jti(token ID) qo'shing va bekor qilinganlarni muddati tugaguncha keshda (Redis) saqlang. - Parol almashtirilganda foydalanuvchining barcha sessiyalari va tokenlarini bekor qiling.
Tekshirish:
TOKEN=<logout'dan oldingi token>
curl -s -X POST https://api.your-domain.uz/v1/logout -H "Authorization: Bearer $TOKEN"
curl -s -o /dev/null -w "%{http_code}\n" https://api.your-domain.uz/v1/me \
-H "Authorization: Bearer $TOKEN"
# kutilgan natija: 401
Laravel: Sanctum va Passport bo'yicha eslatmalar
Sanctum API tokenlari JWT emas: bu tasodifiy satr, bazada (personal_access_tokens) xesh ko'rinishida saqlanadi. Shuning uchun algoritm chalkashligi kabi muammolar bu yerda yo'q va tokenni o'chirish darhol ta'sir qiladi. Lekin ikki narsani tekshiring:
// config/sanctum.php — standart holatda muddat yo'q (null)
'expiration' => 60 * 24, // daqiqalarda
// logout: joriy tokenni o'chirish
$request->user()->currentAccessToken()->delete();
Muddati o'tgan yozuvlarni tozalash uchun php artisan sanctum:prune-expired buyrug'ini rejalashtiring. SPA uchun Sanctum'ning cookie asosidagi sessiya rejimini ishlating — token brauzer xotirasiga tushmaydi.
Passport to'liq OAuth2 server va RS256 bilan imzolangan JWT access tokenlar chiqaradi. Muddatlarni aniq belgilang va kalit fayllarini himoyalang:
Passport::tokensExpireIn(now()->addMinutes(30));
Passport::refreshTokensExpireIn(now()->addDays(14));
storage/oauth-private.key repozitoriyga tushmasin, fayl ruxsatlari cheklangan bo'lsin (chmod 600), production kaliti esa muhit o'zgaruvchisi orqali berilsin.
O'zingiz tekshirish uchun qisqa reja
- Test akkaunt bilan kiring va tokenni oling. Payload'ni dekodlang: unda maxfiy ma'lumot bormi,
exp,iss,audbormi? alg: noneva imzosi o'zgartirilgan token bilan so'rov yuboring —401kutiladi.- Payload'dagi foydalanuvchi ID'sini o'zgartirib ko'ring —
401kutiladi. - Muddati o'tgan token bilan so'rov yuboring.
- Logout'dan keyin eski access va refresh tokenlarni sinang.
- Bitta refresh tokenni ikki marta ishlating.
- Brauzerda DevTools → Application bo'limida, mobil ilovada esa ilova xotirasida token qayerda saqlanayotganini ko'ring.
Token — bu kalit. U qanchalik qisqa yashasa, qanchalik yaxshi saqlansa va qanchalik tez bekor qilinsa, o'g'irlanganda shuncha kam zarar keltiradi.
Checklist
- Server ruxsat etilgan algoritmni qat'iy belgilaydi,
noneqabul qilinmaydi. HS256secret kamida 256 bit tasodifiy, kodda emas; iloji bo'lsa asimmetrik kalit.- Har bir tokenning muddati bor;
exp,iss,audtekshiriladi. - Payload'da maxfiy ma'lumot yo'q.
- Brauzerda token
HttpOnlycookie'da, mobil ilovada Keystore/Keychain'da. - Refresh token har yangilashda almashtiriladi, qayta ishlatish aniqlanadi.
- Logout va parol almashtirish tokenlarni serverda bekor qiladi.
- Sanctum'da
expirationqo'yilgan, Passport kalitlari himoyalangan.
Xulosa
Token xatolari kamdan-kam hollarda murakkab hujumni talab qiladi: ko'pincha muddat qo'yilmagan, logout ishlamaydi yoki token himoyasiz joyda saqlanadi. Bularning barchasi bir necha so'rov bilan tekshiriladi — ekspertiza ham aynan shunday qiladi.
Autentifikatsiya va token mexanizmingizni ekspertizadan oldin ko'rib chiqmoqchimisiz? Skanerlash uchun ariza qoldiring — Claude AI agenti kod va sozlamalarni tahlil qiladi, mutaxassisimiz esa topilmalarni tasdiqlab, tuzatishda yordam beradi.


