Mundarija (32)
- Bu darsda
- 1. Nega bu kerak?
- 1.1 Qurish yoki olish
- 1.2 Nega tajriba, loyiha emas
- 2. Versiya: beta bilan ishlash
- 2.1 npm teglari
- 2.2 Tranzitiv bog'liqlik va "7 kun" qoidasi
- 3. Auth.js qanday qurilgan
- 3.1 Uch fayl
- 3.2 auth.ts
- 3.3 Yo'llar va himoyalangan Route Handler
- 4. Tajriba: HTTP oqimi
- 4.1 CSRF: double-submit
- 4.2 Xato javoblari
- 4.3 Sessiya cookie: JWE
- 4.4 Eng muhim topilma: chiqish JWT'ni o'ldirmaydi
- 5. Sessiya strategiyasi va adapter
- 5.1 JWT yoki baza
- 5.2 Adapter
- 5.3 Google provayderi
- 6. Sahifalar va proxy
- 7. O'zimiz qurgan bilan solishtirish
- 8. Hujumchi nigohi
- 9. Ko'p uchraydigan xatolar
- 10. Mashqlar
- 1-mashq (oson): to'g'ri yoki noto'g'ri
- 2-mashq (o'rta): JWS yoki JWE?
- 3-mashq (qiyin): ikki strategiya simulyatsiyasi
- 11. Loyiha qadami: tajriba yakuni
- 12. Real ishda
- Xulosa
- Manbalar
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'dagilatest— 4.x. Biz uni 23-qismdagiportfolioloyihasining 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-apiauth'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):
"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:
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:
"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]src/auth.ts— hamma sozlama: provayderlar, sessiya, callbacklar. U to'rtta narsa eksport qiladi:handlers,auth,signIn,signOut.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.- Siz himoya qiladigan joy —
auth()ni chaqiradigan Route Handler, sahifa yokiproxy.ts.
3.2 auth.ts
Tajribadagi sozlama (telefon uchun bo'lingan; bo'lingan nusxa portfolio nusxasida tip va lint'dan o'tdi — biz tekshirdik):
// 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 holdanull. Parolni qanday tekshirish — sizning mas'uliyatingiz. Tajribada Parolni xavfsiz saqlash darsidagi argon2id vatimingSafeEqual.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; tokendagirolni sessiyaga o'tkazadi.trustHost: true— prodakshndaAUTH_URLberish 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:
// 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:
// 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:
--- 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: → 401Nima 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 sessiyaTokenni 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.
4.3 Sessiya cookie: JWE
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_SECRETdan 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:
maxAgeni 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):
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:
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:
// 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
npm install next-auth2026-yil oktyabrida v5 ni o'rnatadi.- Auth.js sessiya cookie'sidagi emailni mijoz base64url bilan o'qiy oladi.
jwtstrategiyada chiqishdan keyin eski cookie ishlamaydi.- Credentials provayderida parolni qanday tekshirish — dasturchining ishi.
csrfTokensiz login so'roviMissingCSRFbilan qaytadi.
Yechim
- Noto'g'ri —
latestteg 4.24.15; v5 —betateg. - Noto'g'ri — cookie JWE (5 qism, shifrlangan); oddiy JWT'dagi kabi o'qib bo'lmaydi.
- Noto'g'ri — tajribada eski cookie bilan 200 oldik.
- To'g'ri —
authorizesizning funksiyangiz. - 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
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:
JWS HS256 -
JWE dir A256CBC-HS512
noma'lumJWE'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
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:
jwt true false
db false falseJWT 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 halibetateg, versiya aniq yoziladi. - Provayderlar tayyor; Credentials'da parol tekshiruvi va tezlik cheklovi — siz.
jwtcallback tokenga maydon qo'shadi,sessioncallback uniauth()natijasiga o'tkazadi.- Sukut sessiya — JWE cookie (5 qism,
dir+A256CBC-HS512): mijoz o'qiy olmaydi, o'zgartirsa — 401. - Chiqishdan keyin eski JWT cookie
maxAgegacha ishlaydi — bekor qilish uchundatabasestrategiya va adapter. - Tranzitiv bog'liqliklarni ham tekshiring:
overridesbilan 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
- Auth.js hujjati (v5): https://authjs.dev/getting-started/installation?framework=next-js ; sessiya strategiyalari: https://authjs.dev/concepts/session-strategies ; Credentials: https://authjs.dev/getting-started/authentication/credentials ; adapterlar: https://authjs.dev/getting-started/database
- next-auth npm sahifasi (teglar): https://www.npmjs.com/package/next-auth?activeTab=versions (2026-10-28 da tekshirildi)
- RFC 7516 "JSON Web Encryption (JWE)": https://www.rfc-editor.org/rfc/rfc7516
- npm
overrides: https://docs.npmjs.com/cli/v11/configuring-npm/package-json#overrides - Tajriba (IlmHamroh, 2026-10-28): 23-qism
portfolionusxasida Auth.js — biz ishga tushirdik (Node 24.21.0, next 16.4.0, next-auth 5.0.0-beta.32, @auth/core 0.41.3, i5-12500H, Windows 11). Darsdagi brauzer misollari — biz ishga tushirdik.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!