JWT — rol ko'tarish

≡ Barcha darslar
Tezkor 🔎 Indeks
🎫

JWT — rol ko'tarish

Token roliga ishonish
Dars 14 Jiddiy o'z saytingizda
1

Maqsad

token ichidagi rolni ishonch bilan o'zgartirish

JWT o'zgartirilmaydi — imzo bor. Lekin server ko'p hollarda token ichidagi role maydonini to'g'ridan-to'g'ri ishonch bilan ishlatadi, bazasidan qayta tekshirmaydi. Bu — eng ko'p uchraydigan JWT zaifligi.

2

Tushuntirish

// XAVFLI
const decoded = jwt.verify(token, SECRET);          // imzo tekshirildi — OK
if (decoded.role === 'admin') return adminPanel();
// ↑ imzo to'g'ri, LEKIN eski token hali ham "admin" deydi

// TO'G'RI — rolda DB dan
const decoded = jwt.verify(token, SECRET, {{ algorithms:['HS256'] }});
const user = await prisma.user.findUnique({{ where: {{ id: decoded.sub }} }});
if (user.role === 'admin' && user.isActive) return adminPanel();
if (user.role !== decoded.role) await revokeAll(user.id);   // rol o'zgargan
Ikkita alohida holat

1) Ishonch bilan ishlatish — token'dagi rolda qaror beriladi. 2) Eski token — foydalanuvchi adminlikdan tushdirilgan, lekin eski tokeni 1 soat amal qiladi.

3

Qanday aniqlanadi

# 1) roldan foydalanish joylari
grep -rnE "req\.user\.(role|isAdmin)|decoded\.(role|is_admin)|payload\.role" src/

# 2) rolda DB dan olinadimi?
grep -rnE "findUnique.*user|prisma\.user\.|User\.findOne" src/ | head

# 3) token muddati
grep -rnE "expiresIn|exp:|maxAge" src/ | head
4

Buyruqlar

# 1) oddiy user tokenini oling
TOKEN=$(curl -s -X POST https://site.uz/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"oddiy@site.uz","password":"..."}' | jq -r .token)
echo "$TOKEN" | cut -d. -f2 | base64 -d 2>/dev/null; echo

# 2) rolda o'zgartirib, imzoni saqlab qolamiz (kalitni bilmaymiz)
# → bu imzoni buzadi. Shuning uchun 3-usul qo'llaniladi:

# 3) asosiy test: rolda serverga qarab o'zgaradimi?
curl -s https://site.uz/api/admin/users -H "Authorization: Bearer $TOKEN" | jq .
curl -s https://site.uz/api/me -H "Authorization: Bearer $TOKEN" | jq '.role'
# token'da "user", lekin /api/admin/users 200 qaytarib bo'lsa — zaiflik

# 4) turli ro'l nomlari bilan
for R in admin administrator superadmin super_user root 1 true; do
  echo "$R → $(curl -s -o /dev/null -w '%{http_code}' https://site.uz/api/admin \
    -H "Authorization: Bearer $TOKEN")"
done

# 5) status/flag maydonlari
curl -s https://site.uz/api/me -H "Authorization: Bearer $TOKEN" | jq 'del(.token,.passwordHash)'

# 6) eski token muammusini tekshirish (o'z saytingizda)
#  a) admin tokenni yarating va 1 soat saqlang (test maqsadida)
#  b) foydalanuvchini adminlikdan chiqaring
#  c) eski token bilan /api/admin ni so'rang
curl -s -o /dev/null -w "eskirgan token → HTTP %{http_code}\n" \
  https://site.uz/api/admin -H "Authorization: Bearer $ESKI_TOKEN"
# 200 → muammo bor (token bekor qilinmagan)

# 7) jwks / kid tekshiruvi
curl -s https://site.uz/api/auth/me -H "Authorization: Bearer $TOKEN" | jq '{kid, sub, role, iat, exp}'
5

Natija

✓ MUvaffaqiyat — hujum ISHLADI
Server javobiNima degani
`/api/admin` 200 qaytardi**Rol token'dan olinadi — zaiflik**
`role: "user"` lekin admin panel ochildi**Ishonch bilan qaror**
Tushirilgan foydalanuvchi eski token bilan kirdi**Token bekor qilinmagan**
`isActive: false` lekin kirish qoldi**Holat tekshirilmaydi**
✗ Rad etish — hujum ISHLAMADI
Server javobiNima degani
`/api/admin` → 403**To'g'ri** — rol DB dan tekshiriladi
`role` token'da o'zgarib, javob o'zgarmadi**Ishonchli rol**
Tushirilgandan keyin 401**Token bekor qilindi** — to'g'ri
6

Zararni yopish

1. Rolni DB dan olish (qat'iy)

function auth(req, res, next) {{
  const d = jwt.verify(req.headers.authorization.slice(7), SECRET, {{
    algorithms: ['HS256']
  }});
  req.token = d;                     // faqat kimligi (sub)
  next();
}}

async function loadUser(req, res, next) {{
  req.user = await prisma.user.findUnique({{ where: {{ id: Number(req.token.sub) }} }});
  if (!req.user || !req.user.isActive) return res.status(401).end();
  if (req.user.role !== req.token.role) req.tokenStale = true;   // ogohlantirish
  next();
}}
app.use('/api', auth, loadUser);

// keyin HAR QAYERDA
if (req.user.role === 'admin') ...   // ← token emas, DB

2. Token bekor qilish

# parol o'zgarganda / logout da — token qora ro'yxati
await redis.set(`revoked:${{d.jti}}`, 1, {{ EX: 3600 }});
if (await redis.get(`revoked:${{d.jid}}`)) return fail();

# yoki versiya usuli (eng oddiy)
#  user.tokenVersion raqamini oshirish; token'da versiyani solishtirish
if (d.ver !== req.user.tokenVersion) return fail();

3. Token muddatini qisqartirish

jwt.sign(payload, SECRET, {{ algorithm:'HS256', expiresIn:'15m' }});
// + refresh token (15 daqiqa / 7 kun, faqat /refresh da)
7

Tekshirish ro'yxati

  • Rol `req.user` dan (DB) olinadi, token'dan emas
  • `algorithms: ['HS256']` ko'rsatilgan
  • `isActive` va `emailVerified` tekshiriladi
  • Parol o'zgarganda eski tokenlar bekor qilinadi
  • Access token 15 daqiqa
  • Oddiy user token bilan `/api/admin` so'raldi