IlmHamroh
JavaScript Full-stack/28-qism. Autentifikatsiya va backend xavfsizligi23/31-dars18 daqiqa
Mundarija (32)

Auth.js (NextAuth v5): Next.js'da tayyor kirish tizimi, JWT sessiya va callbacklar

Qisqacha: Auth.js (sobiq NextAuth) — Next.js ilovasiga kirish tizimini bir necha faylda qo'shadigan kutubxona: provayderlar (Google, GitHub, login va parol), sessiya, CSRF himoyasi va auth() funksiyasi tayyor. 2026-yil oktyabrida v5 hali beta (5.0.0-beta.32), npm'dagi latest — 4.x. Biz uni 23-qismdagi portfolio loyihasining nusxasida sinadik: kirish, auth(), callback orqali rol qo'shish va CSRF ishladi. Eng muhim topilma: sukut bo'yicha sessiya — shifrlangan JWT cookie, va chiqishdan oldingi cookie chiqishdan keyin ham ishlayveradi.

Bu darsda

  • Auth.js'ning asosiy qismlarini tushuntira olasiz: auth.ts, provayderlar, sessiya strategiyasi, callbacklar, adapter.
  • Credentials provayderi bilan Next.js ilovasiga kirishni qo'shasiz va himoyalangan Route Handler yozasiz.
  • JWT va bazadagi sessiya farqini o'z tajribamizdagi raqamlar bilan baholaysiz.
  • Beta versiyani loyihaga olishning xavflarini va versiyani qanday qotirishni bilasiz.
  • Tayyor kutubxona va o'zimiz qurgan vazifalar-api auth'ini solishtira olasiz.

Oldin bilishingiz kerak: Route Handlers: route.ts bilan API, proxy.ts (sobiq middleware), JWT anatomiyasi, Session vs JWT qarori va uzoq sessiyalar, Auth kutubxonalari va xizmatlari.

Bu qismning o'n sakkiz darsida auth'ni noldan qurdik: argon2, sessiya, CSRF, 2FA, passkey, API kalitlar. Bu — tushunish uchun eng yaxshi yo'l. Lekin ertaga sizga Next.js'da kichik loyiha kerak bo'lsa-chi, masalan portfoliodagi "kabinet" sahifasi? Hammasini qaytadan yozasizmi? Bugun tayyor kutubxonani sinaymiz va uning ichida nima borligini biz bilgan narsalar bilan solishtiramiz.

1. Nega bu kerak?

1.1 Qurish yoki olish

Auth kutubxonalari va xizmatlari darsida uch yo'lni ko'rdik: o'zingiz yozish, kutubxona, tashqi xizmat. Next.js ekotizimida eng ko'p ishlatiladigan kutubxona — Auth.js. U v4 gacha next-auth deb atalardi, v5 dan boshlab umumiy yadro @auth/core ga ajratildi, Next.js uchun paket nomi esa next-auth bo'lib qoldi.

Auth.js sizga beradi:

  • provayderlar — Google, GitHub va boshqa OAuth/OIDC xizmatlari, email havolasi, login va parol;
  • sessiya — cookie'da shifrlangan JWT yoki bazada;
  • CSRF himoyasi — har POST so'rovida token;
  • auth() — server kodida "hozir kim kirgan?" savoliga bitta chaqiruv.

Lekin u bermaydi: parolni xavfsiz saqlash (bu sizning ishingiz), tezlik cheklovi, 2FA (TOTP), hisobni bloklash, sessiyalar ro'yxati. Bularni o'zingiz qo'shasiz — xuddi o'tgan darslardagidek.

1.2 Nega tajriba, loyiha emas

Bu dars vazifalar-api ga hech narsa qo'shmaydi. Sabablar:

  • vazifalar-api — Express backend, Auth.js esa Next.js uchun qurilgan;
  • kanon qarori — server sessiyasi (bekor qilish mumkin), Auth.js sukut bo'yicha esa JWT;
  • v5 hali beta.

Shuning uchun tajriba 23-qismdagi portfolio loyihasining alohida nusxasida o'tkazildi — asl loyiha o'zgarmadi. Siz ham shunday qiling: portfolio papkangizni nusxalab, tajribani nusxada bajaring.

2. Versiya: beta bilan ishlash

2.1 npm teglari

2026-10-28 holatiga npm'dagi teglar (biz tekshirdik, npm view next-auth dist-tags):

text
"latest": "4.24.15",
"beta": "5.0.0-beta.32"

npm install next-auth — 4.x ni o'rnatadi. v5 kerak bo'lsa, versiyani aniq yozasiz:

bash
npm install next-auth@5.0.0-beta.32

^5.0.0-beta.32 emas, aniq versiya. Semver qoidasida beta versiyalar orasida ham buzuvchi o'zgarishlar bo'lishi mumkin — npm update ertaga boshqa API'ni olib kelmasin. Bu kursning boshidan beri amal qilayotgan qoidamiz: bog'liqliklar aniq versiya bilan.

Tajribadagi versiyalar: next 16.4.0, next-auth 5.0.0-beta.32, @auth/core 0.41.3. next-auth ning peerDependencies qismida next uchun ^14 || ^15 || ^16 ko'rsatilgan.

2.2 Tranzitiv bog'liqlik va "7 kun" qoidasi

O'rnatishda kanon bir topilmaga duch keldi. @auth/core jose kutubxonasiga ^6 bilan bog'langan va npm eng yangi 6.2.13 ni olib keldi — u o'rnatish kunida 7 kundan yangi edi. Yangi chiqqan versiya — ta'minot zanjiri hujumlari uchun eng xavfli oyna. Kanon uni package.json dagi overrides bilan bir oldingi versiyaga qotirdi:

json
"overrides": {
  "jose": "6.2.12"
}

overrides — sizning bevosita bog'liqligingiz bo'lmagan paketning versiyasini butun daraxtda majburlash. Bu qoidani eslab qoling: beta kutubxona olganingizda uning ostida nima kelganini ham tekshiring (npm ls jose).

3. Auth.js qanday qurilgan

3.1 Uch fayl

flowchart LR
  A[src/auth.ts: NextAuth sozlamasi] --> H[handlers]
  A --> F["auth()"]
  H --> R["app/api/auth/[...nextauth]/route.ts"]
  F --> K[app/api/kabinet/route.ts]
  F --> P[server komponent yoki proxy.ts]
  1. src/auth.ts — hamma sozlama: provayderlar, sessiya, callbacklar. U to'rtta narsa eksport qiladi: handlers, auth, signIn, signOut.
  2. app/api/auth/[...nextauth]/route.ts — Auth.js'ning o'z yo'llari: /api/auth/signin, /callback/<provayder>, /session, /csrf, /signout. [...nextauth] — Next.js'ning "qolgan hamma bo'laklar" yo'li.
  3. Siz himoya qiladigan joy — auth() ni chaqiradigan Route Handler, sahifa yoki proxy.ts.

3.2 auth.ts

Tajribadagi sozlama (telefon uchun bo'lingan; bo'lingan nusxa portfolio nusxasida tip va lint'dan o'tdi — biz tekshirdik):

ts
// src/auth.ts — Auth.js (next-auth 5.0.0-beta.32) tajribasi,
// portfolio NUSXASIDA. Provayder — Credentials (lokal demo hisob,
// parol argon2id bilan); Google/GitHub — sinalmagan (hisob kerak).
// Sessiya — JWT (cookie, JWE shifrlangan).
import {
  argon2Sync,
  randomBytes,
  timingSafeEqual,
} from "node:crypto";
import NextAuth from "next-auth";
import Credentials from "next-auth/providers/credentials";

// Demo hisob: parol env'dan (DEMO_PAROL), hash ishga tushishda
// hisoblanadi — haqiqiy loyihada bazadan
const tuz = randomBytes(16);
const hash = (p: string) =>
  argon2Sync("argon2id", {
    message: p,
    nonce: tuz,
    memory: 19456,
    passes: 2,
    parallelism: 1,
    tagLength: 32,
  });
const DEMO = {
  id: "1",
  email: "aziz@example.com",
  name: "Aziz Karimov",
  hash: hash(
    process.env["DEMO_PAROL"] ?? randomBytes(16).toString("hex"),
  ),
};

export const { handlers, auth, signIn, signOut } = NextAuth({
  // next start (lokal) — AUTH_URL o'rniga Host sarlavhasiga ishonish
  trustHost: true,
  session: { strategy: "jwt", maxAge: 60 * 60 },
  providers: [
    Credentials({
      credentials: {
        email: { label: "Email" },
        parol: { label: "Parol", type: "password" },
      },
      authorize: (c) => {
        const email =
          typeof c.email === "string" ? c.email.toLowerCase() : "";
        const parol = typeof c.parol === "string" ? c.parol : "";
        const togri =
          timingSafeEqual(hash(parol), DEMO.hash) &&
          email === DEMO.email;
        return togri
          ? { id: DEMO.id, email: DEMO.email, name: DEMO.name }
          : null;
      },
    }),
  ],
  callbacks: {
    // jwt → session: tokenga rol qo'shish naqshi
    jwt: ({ token }) => ({ ...token, rol: "foydalanuvchi" }),
    session: ({ session, token }) => ({
      ...session,
      rol: token["rol"],
    }),
  },
});

Har qismni o'qiymiz:

  • Credentials — login va parol provayderi. authorize — sizning funksiyangiz: to'g'ri bo'lsa foydalanuvchi obyekti, aks holda null. Parolni qanday tekshirish — sizning mas'uliyatingiz. Tajribada Parolni xavfsiz saqlash darsidagi argon2id va timingSafeEqual.
  • session.strategy: "jwt" — sessiya cookie ichida; maxAge — 1 soat.
  • callbacks.jwt — token yaratilganda yoki yangilanganda chaqiriladi; unga o'z maydoningizni (rol) qo'shasiz.
  • callbacks.session — auth() qaytaradigan obyektni shakllantiradi; tokendagi rol ni sessiyaga o'tkazadi.
  • trustHost: true — prodakshnda AUTH_URL berish yoki ishonchli proksi ortida bo'lish kerak. Lokal sinov uchun yoqildi.

Demo hisob — faqat tajriba uchun: bitta foydalanuvchi, paroli DEMO_PAROL muhit o'zgaruvchisidan, har ishga tushishda tasodifiy. Haqiqiy loyihada authorize bazadan foydalanuvchini topadi.

E'tibor bering: authorize da hash(parol) email tekshiruvidan oldin hisoblanadi. Email noto'g'ri bo'lsa ham argon2 ishlaydi — Ro'yxat va login oqimi darsidagi "javob vaqti emailni oshkor qilmasin" qoidasi.

3.3 Yo'llar va himoyalangan Route Handler

Auth.js yo'llari — bitta qatorlik fayl:

ts
// app/api/auth/[...nextauth]/route.ts
// Auth.js yo'llari: /api/auth/signin, /callback/<provayder>,
// /session, /csrf, /signout
import { handlers } from "@/auth";

export const { GET, POST } = handlers;

Himoyalangan yo'l:

ts
// app/api/kabinet/route.ts — auth() serverda sessiyani o'qiydi
import { auth } from "@/auth";

export async function GET() {
  const s = await auth();
  if (s === null) {
    return Response.json({ xato: "kirish kerak" }, { status: 401 });
  }
  return Response.json({ sessiya: s });
}

auth() cookie'ni o'qiydi, shifrini ochadi, muddatini tekshiradi va session callback natijasini qaytaradi. Kirmagan bo'lsa — null. next build chiqishida ikkala yo'l ham ƒ (dinamik) belgisi bilan chiqdi — so'rovga qarab hisoblanadi, keshlanmaydi.

Sir: AUTH_SECRET muhit o'zgaruvchisi — cookie shifrlash kaliti. Tajribada u har ishga tushishda tasodifiy yaratildi (32 bayt, base64url). Haqiqiy loyihada — .env da, git'ga kirmaydi.

4. Tajriba: HTTP oqimi

Tajribani o'zimiz qayta o'tkazdik (biz ishga tushirdik: Node 24.21.0, next 16.4.0, next-auth 5.0.0-beta.32, next build + next start, so'rovlar curl bilan). Qisqartirilgan chiqishda har qadamning status kodiga va 8-qadamga alohida qarang:

text
--- next build
exit 0 (26 s)
├ ƒ /api/auth/[...nextauth]
├ ƒ /api/kabinet
--- 1) kirmasdan: GET /api/kabinet → 401; /api/auth/session → null
--- 2) /api/auth/csrf cookie'lari:
    authjs.callback-url secure=FALSE httpOnly=1
    authjs.csrf-token secure=FALSE httpOnly=1
--- 3) noto'g'ri parol:
   302 → http://localhost:4365/api/auth/signin?error=CredentialsSignin&code=credentials
--- 4) csrfToken'siz:
   302 → http://localhost:4365/api/auth/signin?error=MissingCSRF
--- 5) to'g'ri parol:
   302 → http://localhost:4365/
    sessiya cookie: 478 belgi, qismlar: 5, header: {"alg":"dir","enc":"A256CBC-HS512","kid":"…"}
--- 6) kirgandan keyin: GET /api/kabinet → {"sessiya":{"user":{"name":"Aziz Karimov","email":"aziz@example.com"},"expires":"2026-10-28T15:24:41.289Z","rol":"foydalanuvchi"}}
--- 7) chiqish:
   302 → http://localhost:4365/
    keyin /api/kabinet → 401
--- 8) chiqishdan oldingi cookie bilan: → 200
--- 9) cookie oxirgi belgisi o'zgartirilsa: → 401

Nima bo'ldi? Kirish, CSRF, xato va JWE shifri kutilgandek ishladi (1–7, 9-qadamlar). Lekin 8-qadam — chiqishdan keyin ham 200 — ogohlantirish belgisi. kid qiymatini qisqartirdik (…), port (4365) — bizning tajriba porti. Endi qadamma-qadam.

4.1 CSRF: double-submit

2-qadam: /api/auth/csrf ikki cookie qo'ydi, ikkalasi ham HttpOnly. Login formasi csrfToken maydonini yuborishi shart — Auth.js uni cookie'dagi qiymat bilan solishtiradi. Bu double-submit naqshi: begona sayt cookie'ni brauzer orqali yubora oladi, lekin uning qiymatini o'qib, formaga qo'ya olmaydi. 4-qadam isboti: token'siz so'rov MissingCSRF bilan qaytdi, parol tekshiruvigacha ham bormadi.

Kirish oqimi to'liq:

sequenceDiagram
  participant B as Brauzer
  participant N as Next.js (Auth.js)
  B->>N: GET /api/auth/csrf
  N-->>B: csrfToken + authjs.csrf-token cookie
  B->>N: POST /api/auth/callback/credentials (email, parol, csrfToken)
  N->>N: token va cookie mosmi? authorize() — argon2id
  N-->>B: 302 + sessiya cookie (JWE)
  B->>N: GET /api/kabinet + cookie
  N->>N: auth() — shifrni ochish, muddat
  N-->>B: 200 sessiya

Tokenni qayerda saqlash va CSRF darsida biz boshqa yo'lni tanlagan edik: Origin va Sec-Fetch-Site sarlavhalari. Ikkalasi ham ishlaydi; Auth.js eski brauzerlarni ham qamrab olish uchun token yo'lini tanlagan.

secure=FALSE — tajriba http://localhost da. Auth.js hujjatiga ko'ra HTTPS'da cookie'lar Secure va __Secure-/__Host- prefiksli bo'ladi — bu sinalmagan.

4.2 Xato javoblari

3-qadam: noto'g'ri parol — 302 va ?error=CredentialsSignin. Javob email yo'qligini ham, parol noto'g'riligini ham farqlamaydi — yaxshi. Lekin e'tibor bering: tezlik cheklovi yo'q. Auth.js parolni million marta tekshirishga qarshilik qilmaydi — bu Rate limiting darsidagi ish, va siz uni o'zingiz qo'shasiz.

5-qadam: sessiya cookie — 478 belgi va nuqta bo'yicha 5 qism. JWT anatomiyasi darsidagi JWT'da 3 qism edi: header, payload, imzo. 5 qism — JWE (JSON Web Encryption): header, shifrlangan kalit, IV, shifrlangan matn va teg.

Header'ni o'qiymiz:

  • "alg":"dir" — kalit to'g'ridan-to'g'ri ishlatiladi (AUTH_SECRET dan olingan);
  • "enc":"A256CBC-HS512" — AES-256-CBC shifrlash + HMAC-SHA-512 butunlik tekshiruvi.

Ya'ni payload'ni (email, rol) mijoz o'qiy olmaydi — oddiy JWT'dan farqli. 9-qadam: cookie'ning bitta belgisini o'zgartirdik — 401. Butunlik tekshiruvi ishladi.

4.4 Eng muhim topilma: chiqish JWT'ni o'ldirmaydi

7-qadamda chiqdik — /api/kabinet endi 401. Lekin 8-qadamda chiqishdan oldin saqlab qo'yilgan cookie'ni qo'lda yubordik va 200 oldik.

Sababi: JWT sessiyada serverda hech narsa saqlanmaydi. "Chiqish" faqat brauzerdagi cookie'ni o'chiradi. Cookie'ning nusxasi (o'g'irlangan, log'ga tushgan, boshqa qurilmada qolgan) maxAge (bizda 1 soat) tugaguncha ishlayveradi. Server uni bekor qila olmaydi — buning uchun bekor qilingan tokenlarning taqiq ro'yxati (denylist) yoki bazadagi sessiya kerak.

Bu — Session vs JWT qarori va uzoq sessiyalar darsida vazifalar-api uchun server sessiyasini tanlaganimizning amaliy isboti. Bizning API'da /chiqish dan keyin o'sha token bilan so'rov — 401, chunki sessiya qatori bazada bekor qilingan.

Tekshirib ko'ring: maxAge ni 30 kunga qo'ysangiz, 8-qadam natijasi qanday o'zgaradi va bu nimani anglatadi?

Javob

Natija o'zgarmaydi — 200, lekin endi o'g'irlangan cookie 30 kun ishlaydi. Qisqa maxAge xavf oynasini kichraytiradi, lekin yopmaydi. Bekor qilish kerak bo'lsa (parol o'zgardi, hisob bloklandi, "hamma qurilmalardan chiqish") — database strategiyasi kerak.

5. Sessiya strategiyasi va adapter

5.1 JWT yoki baza

jwt (sukut) database
sessiya qayerda cookie (JWE) bazadagi jadval
baza kerakmi yo'q ha, adapter orqali
har so'rovda shifrni ochish bazaga so'rov
chiqish / bloklash cookie o'chadi, nusxasi ishlaydi darhol
"hamma qurilmalardan chiqish" yo'q bor

5.2 Adapter

database strategiyasi uchun adapter kerak — Auth.js'ni bazangiz bilan bog'laydigan paket: @auth/prisma-adapter, @auth/drizzle-adapter va boshqalar. Adapter foydalanuvchilar, tashqi hisoblar (Google, GitHub), sessiyalar va tasdiqlash tokenlari jadvallarini boshqaradi. Hujjatdagi shakl (sinalmagan):

ts
import { PrismaAdapter } from "@auth/prisma-adapter";
import { prisma } from "@/prisma";

export const { handlers, auth, signIn, signOut } = NextAuth({
  adapter: PrismaAdapter(prisma),
  session: { strategy: "database" },
  providers: [Google],
});

Adapter jadvallar sxemasini o'zi talab qiladi (Prisma'da — hujjatdagi model'lar). Uni mavjud bazangizga qo'shish — oddiy migratsiya (Prisma Migrate chuqur).

5.3 Google provayderi

OAuth provayderlari Auth.js'ning eng kuchli tomoni. Hujjat bo'yicha Google uchun:

ts
import Google from "next-auth/providers/google";

// AUTH_GOOGLE_ID va AUTH_GOOGLE_SECRET — .env dan avtomatik
providers: [Google],

Google Cloud Console'da ilovaga qaytish manzili https://<domen>/api/auth/callback/google deb yoziladi. Bu tajribada sinalmagan: haqiqiy Google hisobi va ilova ro'yxati kerak. Google bilan kirish darsida vazifalar-api uchun bu oqimni openid-client va lokal soxta provayder bilan qo'lda qurgan edik. Auth.js aynan shu ishni (state, PKCE, nonce, token almashish) ichida bajaradi.

6. Sahifalar va proxy

auth() faqat Route Handler'da emas, server komponentda ham ishlaydi:

tsx
// app/kabinet/page.tsx — server komponent
import { auth } from "@/auth";
import { redirect } from "next/navigation";

export default async function Kabinet() {
  const s = await auth();
  if (s === null) redirect("/api/auth/signin");
  return <p>Salom, {s.user?.name}</p>;
}

Auth.js hujjati proxy.ts (proxy.ts (sobiq middleware)) ichida auth dan foydalanib, kirmaganlarni oldindan yo'naltirishni ham ko'rsatadi. Bu ikkala variant ham tajribada sinalmagan — tajriba Route Handler bilan cheklandi. Bitta qoidani eslang: proxy'dagi tekshiruv — tez "optimistik" yo'naltirish. Haqiqiy tekshiruv baribir ma'lumot o'qiladigan joyda (Route Handler, server komponent, Server Action) bo'lishi kerak.

7. O'zimiz qurgan bilan solishtirish

Imkoniyat vazifalar-api (o'zimiz) Auth.js (tajriba)
parol hash argon2id, rehash siz yozasiz (authorize)
sessiya bazada, darhol bekor JWE cookie (sukut)
CSRF Origin / Sec-Fetch-Site double-submit token
OAuth / OIDC openid-client, qo'lda provayderlar tayyor
2FA, passkey TOTP, WebAuthn o'zingiz qo'shasiz
tezlik cheklovi bor (keyingi darslarda) yo'q
bloklash, qurilmalar bor database + o'zingiz

Halol xulosa: Auth.js — OAuth provayderlarini tez ulash va CSRF, cookie, shifrlash tafsilotlarini to'g'ri qilish uchun yaxshi. Lekin u "xavfsizlik tayyor" degani emas: parol saqlash, tezlik cheklovi, 2FA va sessiyani bekor qilish — baribir sizning ishingiz. Bu qismda o'rganganlaringiz Auth.js bilan ishlaganda ham kerak bo'ladi — aynan qayerda bo'shliq qolganini bilish uchun.

8. Hujumchi nigohi

Har qatorda: hujum, himoya va uni tajribamizda ko'rsatgan qadam.

Hujum Himoya Tajriba / tekshiruv
chiqqandan keyin eski cookie database strategiya yoki qisqa maxAge 8-qadam: 200 — himoya YO'Q
million parol urinishi o'zingiz: tezlik cheklovi 3-qadam: cheklov yo'q
begona saytdan login formasi double-submit token (tayyor) 4-qadam: MissingCSRF
cookie'ni o'zgartirish JWE butunligi 9-qadam: 401
yangi chiqqan tranzitiv paket overrides, 7 kun qoidasi npm ls jose
beta API o'zgarishi aniq versiya package.json da ^ yo'q
AUTH_SECRET sizishi .env, aylantirish (hamma chiqadi) — (sinalmagan)

9. Ko'p uchraydigan xatolar

Xato Nega xavfli To'g'risi
npm install next-auth (v5 kutib) 4.x o'rnatiladi aniq @5.0.0-beta.32
authorize da parolni === bilan ochiq parol, vaqt hujumi argon2id + timingSafeEqual
JWT sessiyada "chiqish = xavfsiz" deb o'ylash nusxa ishlayveradi database yoki qisqa maxAge
AUTH_SECRET ni kodga yozish hamma sessiya xavf ostida .env
faqat proxy.ts da tekshirish ma'lumot joyi ochiq auth() ma'lumot o'qiladigan joyda
trustHost: true ni o'ylamasdan prodakshnda soxta Host sarlavhasi AUTH_URL yoki ishonchli proksi

10. Mashqlar

Mashqlar kurs/mashqlar/28/23-authjs/ da.

1-mashq (oson): to'g'ri yoki noto'g'ri

  1. npm install next-auth 2026-yil oktyabrida v5 ni o'rnatadi.
  2. Auth.js sessiya cookie'sidagi emailni mijoz base64url bilan o'qiy oladi.
  3. jwt strategiyada chiqishdan keyin eski cookie ishlamaydi.
  4. Credentials provayderida parolni qanday tekshirish — dasturchining ishi.
  5. csrfToken siz login so'rovi MissingCSRF bilan qaytadi.
Yechim
  1. Noto'g'ri — latest teg 4.24.15; v5 — beta teg.
  2. Noto'g'ri — cookie JWE (5 qism, shifrlangan); oddiy JWT'dagi kabi o'qib bo'lmaydi.
  3. Noto'g'ri — tajribada eski cookie bilan 200 oldik.
  4. To'g'ri — authorize sizning funksiyangiz.
  5. To'g'ri — tajriba 4-qadami.

2-mashq (o'rta): JWS yoki JWE?

tokenTuri(token) funksiyasini yozing: nuqta bo'yicha 3 qism — "JWS", 5 qism — "JWE", boshqasi — "noma'lum". JWS yoki JWE bo'lsa, birinchi qismni base64url'dan ochib, header'dagi alg va (bo'lsa) enc ni ham qaytaring. Sinov tokenlarini o'zingiz yasang: header'ni JSON.stringify → base64url, qolgan qismlar — istalgan satr.

Yechim
js
const b64url = (t) => btoa(t)
  .replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "");
const dan64url = (t) =>
  atob(t.replaceAll("-", "+").replaceAll("_", "/"));

function tokenTuri(token) {
  const q = token.split(".");
  const tur = q.length === 3 ? "JWS" : q.length === 5 ? "JWE" : null;
  if (tur === null) return "noma'lum";
  const h = JSON.parse(dan64url(q[0]));
  return [tur, h.alg, h.enc ?? "-"].join(" ");
}

const jws = [b64url('{"alg":"HS256","typ":"JWT"}'), "e30", "imzo"]
  .join(".");
const jwe = [b64url('{"alg":"dir","enc":"A256CBC-HS512"}'),
  "", "iv", "shifr", "teg"].join(".");

console.log(tokenTuri(jws));
console.log(tokenTuri(jwe));
console.log(tokenTuri("oddiy-satr"));

Konsolda:

text
JWS HS256 -
JWE dir A256CBC-HS512
noma'lum

JWE'ning ikkinchi qismi bo'sh — alg: "dir" da alohida shifrlangan kalit yo'q, kalit to'g'ridan-to'g'ri ishlatiladi. Shuning uchun Auth.js cookie'sida .. ketma-ketligi uchraydi. JWE header'i ochiq — u faqat "qanday ochish" haqida; payload esa shifrlangan.

3-mashq (qiyin): ikki strategiya simulyatsiyasi

Ikki xil "sessiya tekshiruvchi"ni yozing va bir xil stsenariyda solishtiring. jwtStrategiya — token ichida exp (soniya), tekshiruv faqat muddatga qaraydi. dbStrategiya — Map da sessiyalar, chiqishda yozuv o'chiriladi. Stsenariy: 0-soniyada kirish (maxAge 3600), 100-soniyada chiqish, 200-soniyada eski token bilan so'rov, 4000-soniyada yana so'rov. Har ikki strategiya uchun 200 va 4000 dagi natijani chiqaring.

Yechim
js
const MAX_AGE = 3600;

const jwtStrategiya = {
  kir: (t) => ({ sub: "1", exp: t + MAX_AGE }),
  chiq: () => {},
  tekshir: (token, t) => token.exp > t,
};

const sessiyalar = new Map();
let keyingi = 1;
const dbStrategiya = {
  kir(t) {
    const id = keyingi++;
    sessiyalar.set(id, { tugash: t + MAX_AGE });
    return { sid: id };
  },
  chiq: (token) => sessiyalar.delete(token.sid),
  tekshir(token, t) {
    const s = sessiyalar.get(token.sid);
    return s !== undefined && s.tugash > t;
  },
};

const STRATEGIYALAR = [["jwt", jwtStrategiya], ["db", dbStrategiya]];
for (const [nom, st] of STRATEGIYALAR) {
  const eski = st.kir(0);
  st.chiq(eski, 100);
  console.log(nom, st.tekshir(eski, 200), st.tekshir(eski, 4000));
}

Konsolda:

text
jwt true false
db false false

JWT strategiyada chiqishdan keyin token yana 3400 soniya ishlaydi — tajribamizdagi 8-qadamning aynan o'zi. Baza strategiyasida chiqish darhol kuchga kiradi. 4000-soniyada ikkalasi ham rad — muddat tugagan. Ko'ryapsizmi: JWT'da xavfsizlik maxAge ga, bazada — sizning chiq chaqiruvingizga bog'liq.

11. Loyiha qadami: tajriba yakuni

Tajriba nusxada qoldi va ish oxirida o'chiriladi. portfolio asl loyihasi va vazifalar-api o'zgarmadi. Qaror sabablari «Nega tajriba, loyiha emas» bo'limida; bitta qatorda: kanon server sessiyasini tanlagan, Auth.js esa sukut bo'yicha bekor qilib bo'lmaydigan JWT beradi va v5 hali beta.

Sinalmagan narsalar ro'yxati — halollik uchun: OAuth provayderlari (Google, GitHub), DB adapter va database strategiyasi, server komponent va proxy.ts integratsiyasi, HTTPS'dagi cookie prefikslari, Playwright testlari.

Agar o'z Next.js loyihangizga Auth.js qo'shsangiz, tekshiruv ro'yxati: aniq versiya, overrides bilan tranzitivlar, AUTH_SECRET .env da, authorize da argon2id, tezlik cheklovi, va bekor qilish kerak bo'lsa — database strategiya.

12. Real ishda

  • Next.js loyihalarining katta qismi Auth.js yoki Clerk, Better Auth kabi xizmat va kutubxonalarni ishlatadi. Ichida baribir shu qismning g'oyalari: cookie atributlari, CSRF, JWT/JWE, OAuth.
  • Loyiha egasi o'zgardi. Auth.js sayti 2026-10 holatiga "loyiha endi Better Auth tarkibida" deb yozadi (Auth kutubxonalari va xizmatlari darsida batafsil). Kutubxona tanlashda kim qo'llab-quvvatlashini ham tekshiring.
  • Beta kutubxona prodakshnda — v5 ning birinchi beta'si npm'da 2023-yil oktyabrida chiqqan (5.0.0-beta.0, 2023-10-24), ya'ni u uch yildan beri "beta". Uni prodakshnda ishlatish — jamoa qarori: aniq versiya, yangilashdan oldin o'qilgan o'zgarishlar ro'yxati va testlar bilan.
  • Intervyuda: "NextAuth'da JWT va database sessiya farqi?", "Credentials provayderini ishlatishning xavflari?", "Chiqishdan keyin JWT nega ishlayveradi?".

Xulosa

  • Auth.js (NextAuth v5): auth.ts → handlers, auth, signIn, signOut; yo'llar [...nextauth] da; v5 hali beta teg, versiya aniq yoziladi.
  • Provayderlar tayyor; Credentials'da parol tekshiruvi va tezlik cheklovi — siz.
  • jwt callback tokenga maydon qo'shadi, session callback uni auth() natijasiga o'tkazadi.
  • Sukut sessiya — JWE cookie (5 qism, dir + A256CBC-HS512): mijoz o'qiy olmaydi, o'zgartirsa — 401.
  • Chiqishdan keyin eski JWT cookie maxAge gacha ishlaydi — bekor qilish uchun database strategiya va adapter.
  • Tranzitiv bog'liqliklarni ham tekshiring: overrides bilan qotirish.

Keyingi dars: Helmet va xavfsizlik header'lari — brauzerni ham himoyaga qo'shamiz: CSP, HSTS, X-Content-Type-Options va boshqa sarlavhalar vazifalar-api da.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Auth.js (NextAuth v5): Next.js'da tayyor kirish tizimi, JWT sessiya va callbacklar — IlmHamroh