IlmHamroh
JavaScript Full-stack/28-qism. Autentifikatsiya va backend xavfsizligi17/31-dars17 daqiqa
Mundarija (30)

OneID orqali kirish: davlat identifikatsiya tizimi, PINFL va shaxsiy ma'lumot

Qisqacha: OneID — O'zbekistonning "Raqamli hukumat" foydalanuvchilarini identifikatsiyalovchi yagona tizimi (id.egov.uz). Davlat tashkilotlari unga bepul ulanadi, boshqa tashkilotlar — shartnoma asosida. OneID OAuth 2.0 g'oyasida ishlaydi, lekin ochiq integratsiyalarga qaraganda standart OIDC emas: o'z grant_type qiymatlari, bitta endpoint, ochiq discovery yo'q. Shuning uchun Google uchun yozilgan kod to'g'ridan ishlamaydi — alohida adapter kerak. U PINFL kabi davlat identifikatorini beradi. Bunday ma'lumot qonun bilan himoyalangan: faqat kerak bo'lsa va iloji boricha HMAC tamga ko'rinishida saqlanadi. Biz OneID'ni sinamadik — rasmiy texnik hujjat ulanishda beriladi.

Bu darsda

  • OneID nima, kim va qanday ulanishini bilasiz.
  • Ochiq integratsiyalardagi oqimni standart OIDC bilan solishtira olasiz.
  • Rasmiy hujjatsiz da'volarni qanday tekshirish kerakligini ko'rasiz.
  • PINFL'ni ochiq saqlamasdan, HMAC tamga bilan ishlashni yozasiz.
  • vazifalar-api ga OneID qo'shish rejasini — jadval va adapter darajasida — tuzasiz.

Oldin bilishingiz kerak: OAuth 2.0 va OpenID Connect nazariyasi, Google bilan kirish, Managed va serverless Postgres (shaxsiy ma'lumotlar qonuni va saqlash joyi).

Ikki darsda ikki provayderni ulashni ko'rdik: Google — standart OIDC, Telegram — eski (legacy) usuldagi o'z imzo algoritmi. OneID uchinchi xil holat. Unga ulanishning o'zi rasmiy jarayon, texnik hujjat esa hammaga ochiq emas. Bu darsda kod kam, qaror ko'p. Real integratsiyada ham aynan shunday bo'ladi.

1. Nega bu kerak?

1.1 "Davlat tasdiqlagan" foydalanuvchi

Google "bu odamning emaili — X" deydi. Telegram "bu Telegram hisobi — Y" deydi. Ikkalasi ham odamning haqiqiy shaxsini tasdiqlamaydi: Telegram'da istalgan ism bilan hisob ochish mumkin.

Ba'zi xizmatlarga esa aynan shaxs kerak. Bank onlayn hisob ochadi. Universitet ariza qabul qiladi. Notarius hujjat tayyorlaydi. Davlat portali soliq ma'lumotini ko'rsatadi. Ular "bu — pasporti AA… bo'lgan Aziz Karimov" degan isbotga muhtoj. O'zbekistonda bu vazifani OneID bajaradi.

1.2 vazifalar ga kerakmi?

To'g'risini aytamiz: oddiy vazifalar ro'yxatiga davlat identifikatsiyasi kerak emas. Bu dars — kelajakdagi ishingiz uchun: davlat xizmatlari, fintech, ta'lim platformalari. Aynan shuning uchun kanon OneID'ni loyihaga kiritmadi. Biz faqat rejani tuzamiz va undagi xavfli joylarni ko'ramiz.

2. OneID haqida rasmiy ma'lumot

2.1 Loyiha sahifasi

egov.uz dagi loyiha sahifasida (2026-10-28 da o'qildi) quyidagilar yozilgan:

  • OneID — "Raqamli hukumat" tizimi foydalanuvchilarini identifikatsiyalash uchun yagona axborot tizimi;
  • kirish usullari: login va parol, elektron raqamli imzo (ERI), mobil telefon raqami, masofaviy biometrik identifikatsiya;
  • ba'zi xizmatlar "tasdiqlangan foydalanuvchi" maqomini talab qiladi — u ERI yoki Mobile-ID orqali olinadi;
  • davlat tashkilotlari (mahalliy hokimiyat organlari ham) identifikatsiya xizmatini bepul oladi, boshqa xo'jalik yurituvchi subyektlar — belgilangan tartibda tuzilgan shartnoma asosida, pullik;
  • sahifadagi ko'rsatkich: 11 948 192 foydalanuvchi, kuniga o'rtacha ~8 000 yangi ro'yxatdan o'tish.

Raqamlar sahifadagi holat — ular har kuni o'zgaradi.

2.2 Nima topilmadi

Loyiha sahifasida texnik hujjatga havola yo'q, faqat foydalanuvchi portali (id.egov.uz) va umumiy aloqa manzili bor. Biz ochiq manbalarda rasmiy integratsiya qo'llanmasini topmadik (2026-10-28). Bu odatiy holat: davlat tizimiga ulanish shartnomadan keyin bo'ladi va hujjat ulanayotgan tashkilotga beriladi.

Standart OIDC provayderda discovery hujjati hammaga ochiq turadi. Shuni tekshirib ko'rdik (biz ishga tushirdik, 2026-10-28):

bash
curl -s -o /dev/null -w "%{http_code}\n" \
  https://sso.egov.uz/.well-known/openid-configuration
curl -s -o /dev/null -w "%{http_code}\n" \
  https://sso.egov.uz/sso/.well-known/openid-configuration
text
401
404

Birinchi manzil "avtorizatsiyadan o'tmagan" (401), ikkinchisi "topilmadi" (404). Ochiq discovery yo'q. Demak oldingi darsdagi Oidc klassi — u discovery'dan boshlanadi — OneID bilan to'g'ridan ishlamaydi.

3. Ochiq integratsiyalar nima deydi

3.1 Manba haqida ogohlantirish

Diqqat: Bu bo'limdagi parametrlar rasmiy hujjatdan emas. Ular ochiq manbali ikki mustaqil PHP paketining kodidan (Packagist, 2026-10-28 da o'qildi). Biz ularni sinamadik. Real integratsiyada faqat OneID bergan rasmiy hujjat ustun.

Nega baribir ko'ramiz? Chunki real ishda siz ham shunday vaziyatga tushasiz: hujjat qo'lingizda yo'q, lekin boshqalarning kodi bor. Undan o'rganish mumkin. Ishonish esa mumkin emas. Ikki mustaqil manbada bir xil chiqqan narsa — ehtimoli yuqori faraz. Bir-biriga zid narsa — ochiq savol.

3.2 Oqim

Ikkala paketda bir xil chiqqan tuzilma:

  • hamma amal bitta manzilda: https://sso.egov.uz/sso/oauth/Authorization.do;
  • foydalanuvchini yo'naltirish — response_type=one_code, client_id, redirect_uri, scope, state;
  • kodni tokenga almashtirish — POST, grant_type=one_authorization_code, client_id, client_secret, code;
  • foydalanuvchi ma'lumoti — grant_type=one_access_token_identify va access_token;
  • chiqish — grant_type=one_log_out.
sequenceDiagram
  participant B as Brauzer
  participant A as vazifalar-api
  participant O as OneID
  B->>A: GET /v1/auth/oneid
  A-->>B: 303 → Authorization.do?response_type=one_code&state
  B->>O: login (parol, ERI, Mobile-ID)
  O-->>B: 303 → qaytish?code&state
  B->>A: GET /qaytish?code&state
  A->>O: grant_type=one_authorization_code
  O-->>A: access_token
  A->>O: grant_type=one_access_token_identify
  O-->>A: pin, ism, pasport...
  A-->>B: 303 → ilova, sessiya

Diagramma Google oqimiga o'xshaydi, lekin bir muhim farq bor. Oxirida id_token yo'q: ma'lumot alohida so'rov bilan, access token orqali olinadi. Uchinchi bir ochiq qo'llanmada esa yo'naltirishda response_type=code yozilgan — one_code emas. Manbalar orasida ham farq bor. Bu yana bir bor ko'rsatadi: rasmiy hujjatsiz yakuniy kod yozilmaydi.

3.3 Avtorizatsiya manzili

Yuqoridagi parametrlar bo'yicha yo'naltirish manzilini yig'ish (faqat o'rganish uchun):

js
// OneID avtorizatsiya manzili — ochiq kodli integratsiyalardagi
// parametrlar bo'yicha (rasmiy hujjat emas, SINALMAGAN)
const ONEID = "https://sso.egov.uz/sso/oauth/Authorization.do";

function oneIdUrl(clientId, redirectUri, scope, state) {
  const url = new URL(ONEID);
  url.searchParams.set("response_type", "one_code");
  url.searchParams.set("client_id", clientId);
  url.searchParams.set("redirect_uri", redirectUri);
  url.searchParams.set("scope", scope);
  url.searchParams.set("state", state);
  return url;
}

const url = oneIdUrl("vazifalar", "https://example.com/oneid/qaytish",
  "vazifalar", "s-7Kq");
console.log(url.origin + url.pathname);
for (const [k, v] of url.searchParams) console.log(`  ${k} = ${v}`);

Konsolda:

text
https://sso.egov.uz/sso/oauth/Authorization.do
  response_type = one_code
  client_id = vazifalar
  redirect_uri = https://example.com/oneid/qaytish
  scope = vazifalar
  state = s-7Kq

code_challenge va nonce yo'q. Ochiq integratsiyalarning birortasida ham PKCE ko'rinmaydi. Agar rasmiy hujjat ham PKCE'ni qo'llamasa, butun himoya state va client_secret ga tayanadi. Shuning uchun state ni imzolangan cookie'da saqlash (Google bilan kirish darsidagi naqsh) bu yerda yanada muhim.

3.4 Standart bilan solishtirish

Jihat Google (standart OIDC) OneID (ochiq integratsiyalar bo'yicha)
Discovery bor ochiq emas (401/404)
Endpoint'lar har amalga alohida bitta, grant_type bilan farqlanadi
response_type code one_code (manbalarda farq bor)
id_token bor, imzolangan ko'rinmaydi — ma'lumot alohida so'rovda
PKCE, nonce bor ko'rinmaydi
Kimlik sub user_id, pin (PINFL)

Bitta paketda client_secret foydalanuvchi ma'lumotini olish so'roviga GET parametri sifatida qo'yilgan. Bu xavfli odat: URL'lar server jurnallariga, proksi jurnallariga yoziladi va sir u yerda qoladi. Rasmiy hujjat boshqacha yo'l bersa — o'shani tanlang. Bermasa — o'sha so'rovlarni jurnalga yozmaslikni ta'minlang.

Tekshirib ko'ring: Ochiq paketlarning biri foydalanuvchi identifikatori sifatida user_id ?? pin ?? sess_id ni oladi. Ro'yxatdagi uchinchi qiymatda qanday xavf bor?

Javob

sess_id — OneID sessiyasi identifikatori: har kirishda boshqa bo'ladi. Agar user_id va pin kelmay qolsa va kod sess_id ga tushib ketsa, foydalanuvchi har safar "yangi odam" bo'lib ko'rinadi. Har kirishda yangi hisob ochiladi yoki bog'lanish topilmaydi. Kimlik uchun faqat o'zgarmas identifikator olinadi. U bo'lmasa — xato bilan to'xtash, zaxira qiymatga tushish emas.

4. PINFL va shaxsiy ma'lumot

4.1 PINFL nima

PINFL (JShShIR — jismoniy shaxsning shaxsiy identifikatsiya raqami) — har fuqaroning 14 xonali doimiy raqami. U pasportda yozilgan va pasport almashsa ham o'zgarmaydi. Ochiq integratsiyalarda OneID uni pin maydonida beradi. Ular yana pport_no (pasport raqami), mob_phone_no (telefon), ism-familiya va yuridik shaxslar ro'yxatini ham ko'rsatadi.

Bu — dasturchi qo'liga tushadigan eng nozik ma'lumotlardan biri. PINFL sizsa, uni "yangilab" bo'lmaydi: parol kabi almashtirib bo'lmaydi.

4.2 Qonun va minimallashtirish

"Shaxsga doir ma'lumotlar to'g'risida"gi Qonun (O'RQ-547) bunday ma'lumotlarga qo'llanadi. Saqlash joyi haqidagi talablarni (27-1-modda) Managed va serverless Postgres darsida ko'rgansiz. Bu yerda boshqa tamoyil muhimroq — minimallashtirish: faqat maqsad uchun zarur ma'lumot yig'iladi va saqlanadi.

Amalda bu uchta savol:

  1. Nima uchun kerak? "Bu odam OneID'dan o'tdi" — kirish uchun yetarli. PINFL'ning o'zi kerak emas.
  2. Takrorlanmaslik kerakmi? Masalan, "bitta fuqaro — bitta hisob" talabi. Unda PINFL'ning tamg'asi yetarli, raqamning o'zi emas.
  3. Raqamning o'zi kerakmi? Masalan, soliq hisobotida. Faqat shunda — va shifrlangan ustunda, kirish huquqi cheklangan holda.

Bu yuridik maslahat emas. Real loyihada qonunning amaldagi matnini lex.uz da o'qing, kerak bo'lsa yurist bilan maslahatlashing.

4.3 HMAC tamga

PINFL'dan oddiy SHA-256 hash olish yetmaydi. 14 xonali raqamlar soni — 10¹⁴ dan kam. OTP orqali login darsida 6 xonali kodni sizib chiqqan SHA-256 dan 564 ms da topgan edik. PINFL bundan kattaroq, lekin uning raqamlari tasodifiy emas: ochiq paketlardan biri hatto jinsni PINFL'ning birinchi raqamidan aniqlaydi. Tuzilishi ma'lum raqamda variantlar soni amalda ancha kam. Yechim — sirli kalit bilan HMAC: kalitsiz tamga hech narsa bermaydi.

js
const enc = new TextEncoder();
const hex = (b) => Array.from(new Uint8Array(b),
  (x) => x.toString(16).padStart(2, "0")).join("");

async function kalitYasa(sir) {
  return crypto.subtle.importKey("raw", enc.encode(sir),
    { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
}

async function pinflTamga(pinfl, kalit) {
  if (!/^\d{14}$/.test(pinfl)) throw new Error("PINFL — 14 raqam");
  const t =
    await crypto.subtle.sign("HMAC", kalit, enc.encode(pinfl));
  return hex(t).slice(0, 32);
}

// namuna PINFL — haqiqiy shaxsniki emas; kalitlar ham namuna
const k1 = await kalitYasa("pinfl-kaliti-namuna-faqat-dars-uchun");
const k2 = await kalitYasa("boshqa-ilovaning-kaliti-namuna-00000");

console.log(await pinflTamga("12345678901234", k1));
console.log(await pinflTamga("12345678901234", k1));
console.log(await pinflTamga("12345678901234", k2));
try {
  await pinflTamga("1234567890123", k1);
} catch (e) {
  console.log(e.message);
}

Konsolda:

text
607d50869381758a72d3dcf8bdc91efc
607d50869381758a72d3dcf8bdc91efc
1d1beba84841b5fdd8298983bfdf0bd3
PINFL — 14 raqam
  • Bir PINFL, bir kalit — bir xil tamga: takrorlanishni topish mumkin.
  • Boshqa kalit — boshqa tamga: ikki xil ilovaning bazasini birlashtirib, "bu ikkisi bir odam" deb bo'lmaydi.
  • 13 raqam — rad. Bazaga noto'g'ri qiymat tushmasin.

Kanonda bu kalit qayerdan olinadi? Google bilan kirish darsidagi HKDF bilan: sirlar.kalit("oneid") — yangi maqsad nomi. Hozircha KalitMaqsadi turida bunday qiymat yo'q; OneID qo'shilganda u ham qo'shiladi.

Tekshirib ko'ring: HMAC kaliti ham baza bilan birga sizib chiqsa-chi?

Javob

Unda hujumchi har PINFL variantining tamg'asini hisoblab, bazadagilar bilan solishtira oladi — oddiy hash holatiga qaytamiz. Shuning uchun kalit bazada emas, .env yoki sir ombori kabi alohida joyda saqlanadi (Sirlarni boshqarish). Bu Parolni xavfsiz saqlash darsidagi pepper g'oyasining o'zi: alohida saqlangan sir.

5. vazifalar-api ga qo'shish rejasi

5.1 Jadval tayyor

tashqi_hisoblar jadvaliga hech narsa qo'shish kerak emas. CHECK faqat kichik harfli provayder nomini talab qiladi — oneid mos keladi. subyekt sifatida PINFL tamg'asi yoki OneID'ning o'zgarmas user_id si. Qaysi biri — rasmiy hujjat aytadi.

Lokal bazada sinab ko'rdik (biz ishga tushirdik, PostgreSQL 17.6, kanon sxemasi). Madina (id = 4) OneID'ni ulaydi, subyekt — yuqoridagi tamga:

sql
INSERT INTO tashqi_hisoblar (foydalanuvchi_id, provayder, subyekt)
VALUES (4, 'oneid', '607d50869381758a72d3dcf8bdc91efc')
RETURNING provayder, subyekt, email;

Natija:

text
 provayder |             subyekt              | email
-----------+----------------------------------+-------
 oneid     | 607d50869381758a72d3dcf8bdc91efc |
(1 row)

INSERT 0 1

Endi o'sha PINFL bilan boshqa hisob (Javohir, id = 5) ulanmoqchi:

sql
\set VERBOSITY terse
INSERT INTO tashqi_hisoblar (foydalanuvchi_id, provayder, subyekt)
VALUES (5, 'oneid', '607d50869381758a72d3dcf8bdc91efc');

Natija:

text
ERROR:  duplicate key value violates unique constraint "tashqi_hisoblar_provayder_subyekt_key"

"Bitta fuqaro — bitta hisob" qoidasi bazaning o'zida, PINFL'ning o'zi esa bazada yo'q. email bo'sh: OneID'ning emaili bog'lanishda saqlanmadi — kerak emas.

5.2 Adapter, Oidc emas

Oidc klassi discovery va id_token'ga tayanadi, OneID'da ular yo'q. Shuning uchun alohida klass kerak bo'ladi. U Oidc bilan bir xil shaklda ishlaydi: boshla(res) — URL va imzolangan holat cookie'si; yakunla(req, res, cookie) — kodni almashtirish, ma'lumot so'rash va TashqiKimlik qaytarish. Marshrut va tashqiKirish o'zgarmaydi — ular faqat shu shaklni ko'radi. Bu adapter naqshi: har xil tashqi tizim bitta ichki interfeysga moslashtiriladi.

ts
// OneID adapteri — REJA, kanonda yo'q va SINALMAGAN.
// Oidc bilan bir xil shakl: marshrut farqni bilmaydi
interface TashqiProvayder {
  readonly cookieNomi: string;
  boshla(res: Response): Promise<URL>;
  yakunla(
    req: Request,
    res: Response,
    cookie: string | undefined,
  ): Promise<TashqiKimlik>;
}

Bitta muammo qoladi: tashqiKirish yangi bog'lanish uchun tasdiqlangan email talab qiladi. OneID email bermasligi mumkin. Telegram'dagidek bu yerda ham ikki yo'l bor: "avval email bilan kirib, keyin OneID'ni ulash" yoki "OneID bilan emailsiz hisob". Ikkinchisi sxema o'zgarishini talab qiladi: hozir foydalanuvchilar.email — NOT NULL. Bu — mahsulot qarori, kod qarori emas.

5.3 Test muhiti

Google uchun lokal oidc-provider ishlatdik — u standart provayderni to'liq takrorlaydi. OneID nostandart. Shuning uchun uni test qilishning yagona to'g'ri yo'li — OneID beradigan test muhiti (agar bo'lsa) yoki rasmiy hujjat bo'yicha yozilgan lokal soxta server (simulyator). Simulyatorni hujjatsiz yozish — o'z farazlaringizni o'zingiz tasdiqlash bo'ladi. Shuning uchun kanon buni qilmadi.

6. Hujumchi nigohi

Kanonda OneID kodi yo'q, shuning uchun oxirgi ustun — kelajakdagi adapter uchun test rejasi (yoki darsda allaqachon ko'rganingiz).

Hujum Nima uchun ishlaydi Himoya Qanday tekshiriladi
login CSRF (begona code) PKCE yo'q, state tekshirilmaydi imzolangan state cookie Google testidagi "boshqa brauzer cookie'si" naqshi
bazadan PINFL'lar sizishi raqamlar ochiq saqlangan saqlamaslik yoki HMAC tamga 3-mashq: natijada PINFL yo'q
tamgadan PINFL'ni qayta tiklash oddiy SHA-256, kichik raqamlar fazosi sirli kalit bilan HMAC «HMAC tamga» misoli: boshqa kalit — boshqa tamga
client_secret jurnallarda GET parametri POST tanasi yoki jurnaldan chiqarish jurnal faylida sirni qidirish testi
har kirishda yangi hisob sess_id kimlik deb olingan faqat o'zgarmas identifikator 2-mashq: sess_id li javob — rad
ortiqcha ma'lumot (pasport, telefon) "keyin kerak bo'lar" deb hammasi yoziladi ruxsat ro'yxati (allowlist) 3-mashq: faqat uch maydon
soxta "OneID javobi" qaytish manziliga to'g'ridan ma'lumot ma'lumot faqat server-server so'rovidan qaytishga pin yuborib, e'tiborsiz qolishini tekshirish

Oxirgi qatorga e'tibor bering. Foydalanuvchi ma'lumoti brauzer orqali emas, serverning OneID'ga o'zi yuborgan so'rovidan olinadi. Brauzer faqat code ni olib keladi. Telegram vidjetidan farqi shu: u yerda ma'lumot brauzer orqali kelgani uchun imzo kerak edi.

7. Ko'p uchraydigan xatolar

Xato Nega xavfli To'g'risi
ochiq paket kodini "hujjat" deb olish farazlar, manbalar zid rasmiy hujjat, test muhiti
hamma maydonni bazaga yozish sizishda zarar katta minimal, allowlist
PINFL'ni oddiy SHA-256 bilan "yashirish" taxmin bilan topiladi HMAC, kalit alohida
HMAC kalitini bazada saqlash baza bilan birga sizadi .env, sir ombori
sessiya identifikatorini kimlik qilish har safar yangi odam o'zgarmas identifikator
standart OIDC kutubxonasini majburlash discovery va id_token yo'q adapter
client_secret ni URL'ga qo'yish jurnallarda qoladi POST tanasi

8. Mashqlar

Mashqlar kurs/mashqlar/28/17-oneid/ da.

1-mashq (oson): nimani saqlaymiz

Onlayn kutubxona OneID bilan ulanmoqchi. Talablar: (a) foydalanuvchi kirishi; (b) bitta fuqaro bitta abonement olishi; (c) kitobni kechiktirsa, SMS eslatma yuborish. OneID javobida user_id, pin, full_name, pport_no, mob_phone_no bor. Har maydon uchun yozing: saqlash, tamga sifatida saqlash yoki saqlamaslik.

Yechim
Maydon Qaror Sababi
user_id saqlash (yoki tamga) kirish uchun kimlik, (a)
pin HMAC tamga (b) — takrorlanishni topish, raqam kerak emas
full_name saqlash abonement egasining ismi
pport_no saqlamaslik hech qaysi talabga kerak emas
mob_phone_no foydalanuvchi roziligi bilan saqlash (c) — SMS uchun

Telefon raqamini jim saqlamang. U SMS uchun kerak, lekin foydalanuvchi bundan xabardor bo'lishi kerak. Kanonda telefon alohida tasdiqlanadi (OTP orqali login). Pasport raqami — talablarning hech biriga kerak emas: uni saqlash faqat xavf qo'shadi.

2-mashq (o'rta): javobni kimlikka aylantirish

oneIdKimlik(javob) funksiyasini yozing. U { provayder: "oneid", subyekt, ism, pinflBor } qaytarsin. subyekt — faqat user_id (bo'sh bo'lmagan satr), aks holda null (sess_id ga tushmang). ism — full_name, bo'lmasa first_name va sur_name bo'shliq bilan, ikkalasi ham bo'lmasa "OneID foydalanuvchisi". pinflBor — pin 14 raqammi. PINFL'ning o'zi natijaga kirmasin. Uch javobda sinang. Ishora: ?? va filter(Boolean) (filter: shart bo'yicha tanlash).

Yechim
js
function oneIdKimlik(javob) {
  const id = javob.user_id;
  if (typeof id !== "string" || id === "") return null;
  const ism = javob.full_name
    ?? [javob.first_name, javob.sur_name].filter(Boolean).join(" ");
  return {
    provayder: "oneid",
    subyekt: id,
    ism: ism || "OneID foydalanuvchisi",
    pinflBor: /^\d{14}$/.test(javob.pin ?? ""),
  };
}

// namuna javoblar — ochiq kodli paketlardagi maydon nomlari bilan
const JAVOBLAR = [
  { user_id: "aziz.k", full_name: "KARIMOV AZIZ",
    pin: "12345678901234", pport_no: "AA0000000" },
  { user_id: "malika", first_name: "MALIKA", sur_name: "TOSHEVA" },
  { pin: "12345678901234", sess_id: "S-981" },
];
for (const j of JAVOBLAR) {
  const k = oneIdKimlik(j);
  console.log(k === null
    ? "rad: o'zgarmas identifikator yo'q"
    : `${k.subyekt} | ${k.ism} | ${k.pinflBor}`);
}

Konsolda:

text
aziz.k | KARIMOV AZIZ | true
malika | MALIKA TOSHEVA | false
rad: o'zgarmas identifikator yo'q

Uchinchi javobda sess_id bor, lekin u kimlik emas — funksiya rad etdi. pport_no natijaga umuman kirmadi: biz uni so'ramagan maydonlar ro'yxatidan o'tkazmadik. Namuna javoblardagi user_id qiymatlari o'ylab topilgan. Haqiqiy format — rasmiy hujjatda.

3-mashq (qiyin): bazaga faqat keraklisi

saqlashUchun(javob, kalit) asinxron funksiyasini yozing. U faqat ruxsat ro'yxatidagi (user_id, full_name) satr maydonlarni oladi. Agar pin 14 raqam bo'lsa, pin_tamga qo'shadi — HMAC-SHA256 ning birinchi 32 hex belgisi. Natijada PINFL'ning o'zi hech qayerda bo'lmasligini tekshiring. Ishora: HMAC — «HMAC tamga» bo'limidagi kod; Object.keys, JSON.stringify(…).includes(…) (Object.* metodlarining to'liq sharhi).

Yechim
js
const enc = new TextEncoder();
const hex = (b) => Array.from(new Uint8Array(b),
  (x) => x.toString(16).padStart(2, "0")).join("");

const RUXSAT = ["user_id", "full_name"];

async function saqlashUchun(javob, kalit) {
  const natija = {};
  for (const k of RUXSAT) {
    if (typeof javob[k] === "string") natija[k] = javob[k];
  }
  if (/^\d{14}$/.test(javob.pin ?? "")) {
    const t = await crypto.subtle.sign("HMAC", kalit,
      enc.encode(javob.pin));
    natija.pin_tamga = hex(t).slice(0, 32);
  }
  return natija;
}

const kalit = await crypto.subtle.importKey("raw",
  enc.encode("pinfl-kaliti-namuna-faqat-dars-uchun"),
  { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);

const javob = {
  user_id: "aziz.k", full_name: "KARIMOV AZIZ",
  pin: "12345678901234", pport_no: "AA0000000",
  mob_phone_no: "998900000000", birth_date: "2000-01-01",
};
const s = await saqlashUchun(javob, kalit);
console.log(Object.keys(s));
console.log(s.pin_tamga);
console.log(JSON.stringify(s).includes("12345678901234"));

Konsolda:

text
[ 'user_id', 'full_name', 'pin_tamga' ]
607d50869381758a72d3dcf8bdc91efc
false
  • Oltita maydondan uchtasi qoldi. Pasport, telefon va tug'ilgan sana — tashlandi.
  • Tamga «HMAC tamga» bo'limidagi bilan bir xil: kalit va PINFL o'sha.
  • Oxirgi qator — eng muhim tekshiruv. Natijaning hech qayerida PINFL'ning o'zi yo'q.

Ruxsat ro'yxati (allowlist) taqiq ro'yxatidan (denylist) xavfsizroq. OneID ertaga yangi maydon qo'shsa (masalan, manzil), u avtomatik tashlanadi. Taqiq ro'yxatida esa u jimgina bazaga tushardi.

9. Loyiha qadami: reja, kod yo'q

Bu darsda vazifalar-api o'zgarmaydi. Kanon OneID uchun hisob ochmadi, kalit olmadi va test muhitiga kirmadi. Yuqoridagi adapter interfeysi — reja. Agar kelajakda OneID ulanadigan bo'lsa, quyidagilar tayyor:

  • tashqi_hisoblar jadvali (provayder = 'oneid') — o'zgarishsiz;
  • marshrutlar Map orqali — yangi provayder qo'shishga ochiq;
  • Sirlar — yangi maqsad kaliti uchun bitta qator;
  • imzolangan holat cookie'si — Oidc dagi naqsh.

10. Real ishda

  • Davlat va kvazi-davlat xizmatlari — my.gov.uz va boshqa davlat portallari OneID orqali kiradi. Fintech va ta'lim xizmatlari uchun ham "OneID bilan kirish" tugmasi tanish ko'rinish.
  • Shartnoma va xavfsizlik talablari. Davlat tizimiga ulanish — faqat texnik ish emas: ariza, shartnoma, ba'zan axborot xavfsizligi bo'yicha qo'shimcha talablar. Rejaga hujjatlashtirish vaqtini ham qo'shing.
  • Boshqa davlatlarda ham shunday tizimlar bor: Yevropada eIDAS asosidagi milliy elektron identifikatsiyalar, Hindistonda Aadhaar. Har birining o'z ulanish tartibi bor — bugungi yondashuv (rasmiy hujjat, adapter, minimallashtirish) hammasida ishlaydi.
  • Intervyuda: "Rasmiy hujjat yo'q integratsiyani qanday rejalashtirasiz?", "PINFL'ni qanday saqlaysiz?", "Ma'lumotlarni minimallashtirish nima?", "Adapter naqshi qayerda kerak?".

Xulosa

  • OneID — O'zbekistonning yagona davlat identifikatsiya tizimi; davlat tashkilotlariga bepul, boshqalarga shartnoma bilan.
  • Ochiq integratsiyalarga ko'ra u nostandart OAuth: bitta endpoint, o'z grant_type lari, ochiq discovery va id_token yo'q.
  • Rasmiy hujjatsiz yakuniy kod yozilmaydi; ochiq paket kodi — faraz manbai, haqiqat emas.
  • PINFL — doimiy davlat identifikatori: saqlamaslik, kerak bo'lsa HMAC tamga, kalit bazadan alohida.
  • Faqat ruxsat ro'yxatidagi maydonlar saqlanadi; o'zgarmas identifikator bo'lmasa — rad.
  • vazifalar-api tayyor: tashqi_hisoblar va marshrutlar o'zgarmaydi, OneID uchun adapter kerak bo'ladi.

Keyingi dars: Auth kutubxonalari va xizmatlari — 1 470 qator o'zimiz yozgan auth kodini tayyor yechimlar bilan solishtiramiz: Passport, Better Auth, Auth.js, Keycloak, Auth0, Clerk, Supabase Auth.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
OneID orqali kirish: davlat identifikatsiya tizimi, PINFL va shaxsiy ma'lumot — IlmHamroh