IlmHamroh
Python kursi/Karyera va katta loyihalar2/12-dars18 daqiqa
Mundarija (22)

31.2-dars: Loyiha 2 — REST API + baza + auth

31-QISM — KARYERA VA KATTA LOYIHALAR · 2-dars


1. Kirish va motivatsiya

CLI vosita 31.1-bob kichik to'liq loyiha edi. Endi kattaroq va real dunyoda eng ko'p uchraydigan loyiha: to'liq REST API — ma'lumotlar bazasi va autentifikatsiya bilan. Deyarli har veb/mobil ilova ortida shunday API bor: foydalanuvchilar ro'yxatdan o'tadi, kiradi (auth), ma'lumot yaratadi/o'qiydi/o'zgartiradi (CRUD), hammasi bazada saqlanadi. Bu loyiha uch asosiy qismni birlashtiradi: API qatlami (FastAPI — endpointlar, so'rov/javob), ma'lumotlar bazasi (ORM — SQLAlchemy, jadvallar, so'rovlar), autentifikatsiya (JWT — token, himoyalangan endpointlar). Bu — backend dasturchining kundalik ishi. Uni to'liq qurish sizni "ishga tayyor" qiladi.

REST API loyihasi — ma'lumotlar bazasi va autentifikatsiya bilan to'liq backend: API qatlami (FastAPI — endpointlar, Pydantic model, so'rov/javob — 23-qism), baza (ORM — SQLAlchemy, model→jadval, CRUD — 23-qism), autentifikatsiya (JWT — token, Depends himoya, parol hash), qatlamli tuzilish (router/xizmat/model — ajratish 27-qism), migratsiya (Alembic — sxema o'zgarishi). Foydalanish: veb/mobil backend, real xizmat. Bu 23-qism (API/baza), 31.1 (loyiha) ni kengaytiradi. Bu 23-qism (REST/ORM), 31.4 (mikroservis) bilan bog'liq. REST API — API+baza+auth. To'liq backend.

Real vaziyat. Vazifa boshqaruv ilovasi (todo app) uchun backend kerak edi: foydalanuvchilar ro'yxatdan o'tadi (/register), kiradi (/login — JWT token), o'z vazifalarini yaratadi/ko'radi/o'chiradi (/tasks — CRUD, faqat o'ziniki). FastAPI (endpointlar), SQLAlchemy (User, Task jadvallari — baza), JWT (token — kim kirgan), Depends (himoya — token tekshir). Parol hash (bcrypt — ochiq saqlanmaydi). Frontend (React 30.15) shu API bilan gaplashdi (JSON). Real, ishlaydigan backend — portfolioda kuchli 31.8-bob. REST API — foydalanuvchi, auth, CRUD (baza).

Bu darsda to'liq REST API loyihasini o'rganamiz.

Bu darsda:

  • REST API loyiha tuzilishi
  • API qatlami (FastAPI)
  • Ma'lumotlar bazasi (ORM)
  • Autentifikatsiya (JWT)
  • Himoyalangan endpointlar (Depends)
  • Loyiha amaliyoti
  • Xavfsizlik va migratsiya
  • Amaliy: REST API modeli

ℹ To'liq API ko'p vosita/baza talab qiladi; misollar API/auth mantiqini (deterministik) modellashtiradi.


2. Nazariya — chuqur tushuntirish

2.1. REST API loyiha tuzilishi

Qatlamli backend tuzilishi:

todo_api/
├── app/
│   ├── main.py            # FastAPI ilova (kirish)
│   ├── models.py          # ORM modellar (User, Task)
│   ├── schemas.py         # Pydantic (so'rov/javob)
│   ├── database.py        # baza ulanishi
│   ├── auth.py            # JWT, parol hash
│   └── routers/
│       ├── users.py       # /register, /login
│       └── tasks.py       # /tasks CRUD
├── alembic/               # migratsiyalar
├── tests/
└── pyproject.toml

REST API loyiha tuzilishi — qatlamli backend tartibi: main.py (FastAPI ilova — kirish), models.py (ORM modellar — User, Task jadvallari), schemas.py (Pydantic — so'rov/javob validatsiya), database.py (baza ulanishi), auth.py (JWT, parol hash), routers/ (endpointlar — users.py, tasks.py), alembic/ (migratsiyalar). Sabab: real API qatlamli (ajratish 27-qism — model, sxema, router, auth alohida); har qatlam bir vazifa (model — baza, schema — validatsiya, router — endpoint). Bu 27-qism (arxitektura — qatlamlar) amaliyoti. REST API — main, models, schemas, routers, auth. Qatlamli. Ajratish.

2.2. API qatlami (FastAPI)

Endpointlar va validatsiya:

python
# routers/tasks.py — FastAPI endpoint
from fastapi import APIRouter, Depends
from app.schemas import TaskYarat, TaskJavob

router = APIRouter(prefix="/tasks")


@router.post("/", response_model=TaskJavob)
def vazifa_yarat(vazifa: TaskYarat, user=Depends(joriy_user)):
    # vazifa — Pydantic (validatsiya avtomatik)
    # user — auth (himoyalangan)
    yangi = Task(matn=vazifa.matn, user_id=user.id)
    # bazaga saqlash...
    return yangi

API qatlami (FastAPI) — endpointlar va so'rov/javob: router (APIRouter — endpointlar guruhi, /tasks), endpoint (@router.post — HTTP metod + yo'l), Pydantic (TaskYarat — so'rov validatsiya, TaskJavob — javob shakli), Depends (bog'liqlik — auth, baza sessiya). Sabab: API foydalanuvchi bilan HTTP orqali gaplashadi (23-qism REST); FastAPI buni oson qiladi (Pydantic — avtomatik validatsiya, response_model — javob shakli, avtomatik hujjat — Swagger). Depends — qayta ishlatiladigan bog'liqlik (auth, sessiya). Bu 23-qism (FastAPI) markazi. API qatlami — router, endpoint, Pydantic, Depends. Validatsiya avtomatik.

2.3. Ma'lumotlar bazasi (ORM)

Modellar va CRUD:

python
# models.py — SQLAlchemy ORM
from sqlalchemy import Column, Integer, String, ForeignKey


class User(Base):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True)
    email = Column(String, unique=True)
    parol_hash = Column(String)


class Task(Base):
    __tablename__ = "tasks"
    id = Column(Integer, primary_key=True)
    matn = Column(String)
    user_id = Column(Integer, ForeignKey("users.id"))   # bog'lanish

Ma'lumotlar bazasi (ORM) — modellar va so'rovlar: model (class User(Base) — jadval → Python klass, Column — ustunlar), bog'lanish (ForeignKey — Task→User, kim yaratdi), CRUD (session.add — yaratish, session.query — o'qish, o'zgartirish, o'chirish — 23-qism), sessiya (Session — baza aloqasi). Sabab: ma'lumot saqlanishi kerak (baza — doimiy); ORM (SQLAlchemy) Python obyekt ↔ SQL jadval (so'rov qo'lda emas — 23-qism). ForeignKey bog'lanish (Task egasi — User). Bu 23-qism (ORM) amaliyoti. Baza — model (jadval), ForeignKey (bog'lanish), CRUD. ORM. Doimiy saqlash.

2.4. Autentifikatsiya (JWT)

Kim kirgan — token bilan:

python
# auth.py — JWT autentifikatsiya
from passlib.hash import bcrypt
import jwt


def parol_hash(parol: str) -> str:
    return bcrypt.hash(parol)          # ochiq saqlanmaydi


def parol_tekshir(parol: str, hash: str) -> bool:
    return bcrypt.verify(parol, hash)


def token_yarat(user_id: int) -> str:
    return jwt.encode({"user_id": user_id}, MAXFIY_KALIT, algorithm="HS256")

Autentifikatsiya (JWT) — kim kirganini aniqlash: parol hash (bcrypt — parol ochiq saqlanmaydi, hash — qaytarilmaydi, tekshiriladi), JWT (JSON Web Token — kirganda token beriladi, user_id ichida, imzolangan — soxtalashtirib bo'lmaydi), token_yarat (jwt.encode — kirishda), token_tekshir (jwt.decode — har so'rovda). Sabab: API kim so'rov qilganini bilishi kerak (himoya); parol har so'rovda emas (token — bir marta kir, keyin token); parol hash (o'g'rilansa — ochiq emas, xavfsizlik). JWT holatsiz (server token ichidan biladi — sessiya saqlamaydi). Auth — parol hash + JWT token. bcrypt, jwt. Xavfsiz.

2.5. Himoyalangan endpointlar (Depends)

Token tekshirish — avtomatik:

python
# himoyalangan endpoint (Depends bilan)
from fastapi import Depends, HTTPException


def joriy_user(token: str = Depends(oauth2_scheme)) -> User:
    try:
        malumot = jwt.decode(token, MAXFIY_KALIT, algorithms=["HS256"])
        return baza_user(malumot["user_id"])
    except jwt.InvalidTokenError:
        raise HTTPException(status_code=401, detail="Ruxsat yo'q")


@router.get("/tasks")
def vazifalar(user=Depends(joriy_user)):    # himoyalangan!
    return user_vazifalari(user.id)          # faqat o'zining

Himoyalangan endpointlar (Depends) — token avtomatik tekshirish: joriy_user (bog'liqlik — token'dan user_id oladi, bazadan User, xato → 401), Depends(joriy_user) (endpoint'ga qo'shiladi — token tekshiriladi, User beriladi). Sabab: himoyalangan endpoint kim so'raganini bilishi kerak (token tekshir); Depends buni avtomatik qiladi (har himoyalangan endpoint'ga qo'sh — token yo'q/xato → 401 rad). Foyda: qayta ishlatiladi (bir joriy_user, ko'p endpoint), ajratiladi (auth logika alohida). Foydalanuvchi faqat o'zinikini ko'radi (user.id bilan). Himoyalangan — Depends (token tekshir). joriy_user. 401 rad.

2.6. Loyiha amaliyoti

REST API loyiha amaliyotlari: qatlamli (model/schema/router/auth ajrat — 27-qism); Pydantic (so'rov/javob validatsiya — xato oldini); ORM (SQLAlchemy — model, CRUD, sessiya); JWT (auth — token, holatsiz); parol hash (bcrypt — ochiq emas); Depends (himoya, sessiya — qayta ishlatish); migratsiya (Alembic — sxema o'zgarishi); test (endpoint test — TestClient, 20-qism); .env (maxfiy kalit — CLAUDE.md, commit emas). Tuzoqlar: parol ochiq (hash kerak), maxfiy kalit kodda (.env), token tekshirmaslik (himoya yo'q), boshqa foydalanuvchi ma'lumoti (o'ziniki tekshir). Amaliyot — qatlamli, validatsiya, ORM, JWT, hash. REST API — xavfsiz, tartibli backend.

2.7. Xavfsizlik va migratsiya

REST API xavfsizlik va migratsiya: parol hash (bcrypt/argon2 — ochiq saqlama, CLAUDE.md); maxfiy kalit (.env — JWT kalit, commit emas — CLAUDE.md); token muddati (JWT exp — vaqt o'tsa bekor); HTTPS (token tarmoqda — shifrlangan); ruxsat tekshirish (foydalanuvchi o'zinikini — boshqani emas); SQL in'ektsiya (ORM oldini — 23-qism); migratsiya (Alembic — sxema o'zgarishi, alembic revision + upgrade, ma'lumot yo'qotmasdan). Sabab: API ommaviy (internetda — hujum xavfi); xavfsizlik kritik (parol, token, ruxsat); migratsiya sxemani boshqaradi (jadval o'zgarsa — 23-qism). Tuzoqlar: parol ochiq, kalit commit, ruxsatSIz, migratsiyaSIz sxema o'zgartirish (baza buziladi). Xavfsizlik — hash, .env, ruxsat, HTTPS. Migratsiya — Alembic. Kritik.

2.8. REST API — backend dasturchining asosiy ishi

REST API loyiha asosiy g'oyasi — backend dasturchining asosiy ishi: deyarli har veb/mobil ilova ortida shunday API (foydalanuvchi, auth, CRUD, baza) — bu backend dasturchi kundalik ishi. Loyiha uch qatlamni birlashtiradi: API (FastAPI — endpoint, validatsiya), baza (ORM — model, CRUD), auth (JWT — token, himoya). Bu 23-qism (veb, API, baza) ni to'liq amaliyotga aylantiradi (real backend — skript/CLI emas). Xavfsizlik markazda (parol hash, token, ruxsat — real dunyoda kritik). Bu 31-qism (karyera) ning eng amaliy loyihasi (backend ish o'rinlari ko'p); portfolioda kuchli (31.8 — "men to'liq backend qura olaman"). Keyingi loyihalar (ETL 31.3, mikroservis 31.4) buni kengaytiradi. REST API — backend asosi. API+baza+auth. Ishga tayyor.


3. Tez ma'lumotnoma

REST API TUZILISHI (qatlamli):
   main.py (FastAPI) · models.py (ORM) · schemas.py (Pydantic)
   auth.py (JWT) · routers/ (endpoint) · alembic/ (migratsiya)
python
# API QATLAMI (FastAPI)
@router.post("/tasks", response_model=TaskJavob)
def yarat(vazifa: TaskYarat, user=Depends(joriy_user)):
    return Task(matn=vazifa.matn, user_id=user.id)

# BAZA (ORM — SQLAlchemy)
class Task(Base):
    id = Column(Integer, primary_key=True)
    user_id = Column(Integer, ForeignKey("users.id"))

# AUTH (JWT + hash)
parol_hash = bcrypt.hash(parol)               # ochiq saqlanmaydi
token = jwt.encode({"user_id": id}, KALIT)    # kirishda

# HIMOYA (Depends)
def joriy_user(token=Depends(scheme)) -> User:
    malumot = jwt.decode(token, KALIT)        # tekshir (yo'q → 401)
    return baza_user(malumot["user_id"])
XAVFSIZLIK: parol hash · .env (kalit) · token muddat · ruxsat (o'ziniki)
QOIDA: qatlamli · validatsiya · JWT · hash · Alembic migratsiya

REST API xulosasi

REST API — API + baza + auth (to'liq backend, qatlamli)
API qatlami — FastAPI (endpoint, Pydantic, Depends)
Baza — ORM (SQLAlchemy — model, ForeignKey, CRUD)
Auth — JWT token + parol hash (bcrypt, holatsiz)
Himoya — Depends (token tekshir, 401) · xavfsizlik kritik

4. Batafsil misollar

To'liq API ko'p vosita/baza talab qiladi; misollar API/auth mantiqini (deterministik) modellashtiradi.

Misol 1 — Qatlamli tuzilish

python
"""REST API qatlamli tuzilishi (model)."""


QATLAMLAR = {
    "main.py": "FastAPI ilova (kirish)",
    "models.py": "ORM modellar (User, Task)",
    "schemas.py": "Pydantic (so'rov/javob)",
    "auth.py": "JWT, parol hash",
    "routers/users.py": "/register, /login",
    "routers/tasks.py": "/tasks CRUD",
}


def main() -> None:
    print("=== 1. Qatlamlar ===")
    for fayl, vazifa in QATLAMLAR.items():
        print(f"  {fayl:20} — {vazifa}")

    print("\n=== 2. Ajratish (27-qism) ===")
    print("  har qatlam bir vazifa (model, schema, router)")

    print("\n=== 3. Router ===")
    print("  users (auth) + tasks (CRUD) alohida")

    print("\n=== 4. Tartibli ===")
    print("  qatlamli — test, saqlash oson")
    print("  ⭐ REST API — qatlamli tuzilish (ajratish)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Qatlamlar ===
  main.py              — FastAPI ilova (kirish)
  models.py            — ORM modellar (User, Task)
  schemas.py           — Pydantic (so'rov/javob)
  auth.py              — JWT, parol hash
  routers/users.py     — /register, /login
  routers/tasks.py     — /tasks CRUD

=== 2. Ajratish (27-qism) ===
  har qatlam bir vazifa (model, schema, router)

=== 3. Router ===
  users (auth) + tasks (CRUD) alohida

=== 4. Tartibli ===
  qatlamli — test, saqlash oson
  ⭐ REST API — qatlamli tuzilish (ajratish)

Nima ko'rsatdi: 2.1-bo'lim.

Misol 2 — Parol hash (xavfsizlik)

python
"""Parol hash: ochiq saqlanmaydi, tekshiriladi (model)."""


def soxta_hash(parol: str) -> str:
    # bcrypt modeli (real bcrypt qaytarib bo'lmas)
    return "hash$" + str(sum(ord(c) for c in parol))


def parol_tekshir(parol: str, saqlangan_hash: str) -> bool:
    return soxta_hash(parol) == saqlangan_hash


def main() -> None:
    parol = "MaxfiyParol123"

    print("=== 1. Ro'yxatdan o'tish ===")
    h = soxta_hash(parol)
    print(f"  parol → hash: {h}")
    print("  bazaga HASH saqlanadi (parol emas!)")

    print("\n=== 2. Kirish (to'g'ri parol) ===")
    print(f"  tekshir: {parol_tekshir('MaxfiyParol123', h)}")

    print("\n=== 3. Kirish (noto'g'ri parol) ===")
    print(f"  tekshir: {parol_tekshir('NotogriParol', h)}")

    print("\n=== 4. Nega hash ===")
    print("  baza o'g'irlansa — parol ochiq emas (xavfsiz)")
    print("  ⭐ Parol hash — ochiq saqlanmaydi (bcrypt)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Ro'yxatdan o'tish ===
  parol → hash: hash$1282
  bazaga HASH saqlanadi (parol emas!)

=== 2. Kirish (to'g'ri parol) ===
  tekshir: True

=== 3. Kirish (noto'g'ri parol) ===
  tekshir: False

=== 4. Nega hash ===
  baza o'g'irlansa — parol ochiq emas (xavfsiz)
  ⭐ Parol hash — ochiq saqlanmaydi (bcrypt)

Nima ko'rsatdi: 2.4-bo'lim.

Misol 3 — JWT token (kim kirgan)

python
"""JWT token: kirishda beriladi, so'rovda tekshiriladi (model)."""

import json


def token_yarat(user_id: int) -> str:
    # JWT modeli (payload + soxta imzo)
    payload = json.dumps({"user_id": user_id})
    imzo = str(sum(ord(c) for c in payload))
    return f"{payload}.{imzo}"


def token_tekshir(token: str) -> dict:
    payload_str, imzo = token.rsplit(".", 1)
    kutilgan = str(sum(ord(c) for c in payload_str))
    if imzo != kutilgan:
        raise ValueError("Soxta token (401)")
    return json.loads(payload_str)


def main() -> None:
    print("=== 1. Kirish (token beriladi) ===")
    token = token_yarat(42)
    print(f"  token: {token}")

    print("\n=== 2. So'rov (token tekshiriladi) ===")
    malumot = token_tekshir(token)
    print(f"  user_id: {malumot['user_id']}")

    print("\n=== 3. Soxta token ===")
    try:
        token_tekshir("{\"user_id\": 999}.000")
    except ValueError as e:
        print(f"  rad etildi: {e}")

    print("\n=== 4. Holatsiz ===")
    print("  server token ichidan biladi (sessiya yo'q)")
    print("  ⭐ JWT — kim kirgan (imzolangan token)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Kirish (token beriladi) ===
  token: {"user_id": 42}.1255

=== 2. So'rov (token tekshiriladi) ===
  user_id: 42

=== 3. Soxta token ===
  rad etildi: Soxta token (401)

=== 4. Holatsiz ===
  server token ichidan biladi (sessiya yo'q)
  ⭐ JWT — kim kirgan (imzolangan token)

Nima ko'rsatdi: 2.4, 2.5-bo'limlar.

Misol 4 — Ruxsat tekshirish (o'ziniki)

python
"""Ruxsat: foydalanuvchi faqat o'zinikini ko'radi (model)."""


VAZIFALAR = [
    {"id": 1, "matn": "Xarid", "user_id": 42},
    {"id": 2, "matn": "Uchrashuv", "user_id": 42},
    {"id": 3, "matn": "Boshqaning vazifasi", "user_id": 99},
]


def user_vazifalari(user_id: int) -> list:
    # faqat shu foydalanuvchining vazifalari
    return [v for v in VAZIFALAR if v["user_id"] == user_id]


def main() -> None:
    print("=== 1. Foydalanuvchi 42 kirdi ===")
    v42 = user_vazifalari(42)
    for v in v42:
        print(f"  {v['id']}: {v['matn']}")

    print("\n=== 2. Faqat o'ziniki ===")
    print(f"  {len(v42)} ta vazifa (99'niki ko'rinmaydi)")

    print("\n=== 3. Foydalanuvchi 99 ===")
    v99 = user_vazifalari(99)
    print(f"  {len(v99)} ta vazifa (faqat o'ziniki)")

    print("\n=== 4. Xavfsizlik ===")
    print("  user.id bilan filtr (boshqaniki ko'rinmaydi)")
    print("  ⭐ Ruxsat — foydalanuvchi faqat o'zinikini")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Foydalanuvchi 42 kirdi ===
  1: Xarid
  2: Uchrashuv

=== 2. Faqat o'ziniki ===
  2 ta vazifa (99'niki ko'rinmaydi)

=== 3. Foydalanuvchi 99 ===
  1 ta vazifa (faqat o'ziniki)

=== 4. Xavfsizlik ===
  user.id bilan filtr (boshqaniki ko'rinmaydi)
  ⭐ Ruxsat — foydalanuvchi faqat o'zinikini

Nima ko'rsatdi: 2.5, 2.7-bo'limlar.


5. To'g'ri va noto'g'ri tushunishlar

Noto'g'ri fikr To'g'risi
"Hammasi bir faylda" Qatlamli (model/schema/router/auth)
"Parol ochiq saqlansa mayli" Hash (bcrypt — ochiq emas)
"Maxfiy kalit kodda" .env (commit emas — CLAUDE.md)
"Token tekshirmasa mayli" Depends (yo'q → 401)
"Har kim hammani ko'radi" Ruxsat (o'ziniki — user.id)
"Validatsiya qo'lda" Pydantic (avtomatik)
"Sxema qo'lda o'zgartir" Alembic (migratsiya)
"Sessiya server saqlaydi" JWT holatsiz (token ichida)

6. Keng tarqalgan xatolar va yechimlari

1. Parol ochiq saqlash

python
User(parol="MaxfiyParol")   # ochiq (xavfli — CLAUDE.md)      # ⚠️
User(parol_hash=bcrypt.hash(parol))   # hash                   # ✅

2. Maxfiy kalit kodda

python
KALIT = "maxfiy123"   # kodda (commit — xavfli)               # ⚠️
KALIT = os.environ["JWT_KALIT"]   # .env (commit emas)         # ✅

3. Himoyasiz endpoint

python
@router.get("/tasks")
def vazifalar():   # token tekshirilmaydi (har kim)           # ⚠️
def vazifalar(user=Depends(joriy_user)):   # himoya           # ✅

4. Ruxsat tekshirmaslik

python
Task.query.all()   # barcha (boshqaniki ham)                  # ⚠️
Task.query.filter(user_id=user.id)   # o'ziniki               # ✅

5. Validatsiya yo'q

python
def yarat(data: dict):   # tekshirilmagan kirish              # ⚠️
def yarat(vazifa: TaskYarat):   # Pydantic (validatsiya)       # ✅

6. Migratsiyasiz sxema o'zgartirish

python
# baza jadvaliga qo'lda ustun (nomuvofiqlik)                  # ⚠️
# alembic revision + upgrade (migratsiya)                      # ✅

7. Token muddatsiz

python
jwt.encode({"user_id": id})   # abadiy (o'g'irlansa xavf)     # ⚠️
jwt.encode({"user_id": id, "exp": muddat})   # muddat          # ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 23-qism (o'tilgan): FastAPI, REST, ORM
  • 31.4-dars: Mikroservisli tizim — API kengaytmasi
  • 31.1-dars (o'tilgan): Loyiha tuzilishi
  • 28-qism (o'tilgan): Docker/deploy — API joylashtirish
  • 31.8-dars: Portfolio — loyihani ko'rsatish

8. Eng yaxshi amaliyotlar

  1. Qatlamli (model/schema/router/auth ajrat).

  2. Parol hash (bcrypt — ochiq emas).

  3. Maxfiy kalit .env (commit emas — CLAUDE.md).

  4. Depends (himoya, sessiya — qayta ishlatish).

  5. Ruxsat tekshir (foydalanuvchi o'ziniki).

  6. Pydantic (so'rov/javob validatsiya).

  7. Alembic (migratsiya — sxema o'zgarishi).

  8. Token muddat (exp — vaqt o'tsa bekor).


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
1.  # REST API qatlamlari?
2.  # nega qatlamli?
3.  # FastAPI endpoint?
4.  # Pydantic nima?
5.  # ORM model nima?
6.  # ForeignKey nima?
7.  # parol hash nega?
8.  # JWT nima?
9.  # JWT holatlimi?
10. # Depends nima?
11. # ruxsat nima?
12. # migratsiya nima?
Javoblar
  1. main, models, schemas, auth, routers
  2. Ajratish (test, saqlash oson — 27-qism)
  3. HTTP metod + yo'l (@router.post)
  4. So'rov/javob validatsiya (avtomatik)
  5. Jadval → Python klass (Column)
  6. Bog'lanish (Task → User)
  7. Ochiq saqlanmaydi (o'g'irlansa xavfsiz)
  8. Token (kim kirgan, imzolangan)
  9. Yo'q (holatsiz — token ichida)
  10. Bog'liqlik (auth, sessiya — qayta ishlatish)
  11. Foydalanuvchi faqat o'zinikini
  12. Sxema o'zgarishi (Alembic)

Vazifa 2: Xatolarni tuzating

python
1.  User(parol="MaxfiyParol")

2.  KALIT = "maxfiy123"   # kodda

3.  def vazifalar():   # himoyasiz

4.  Task.query.all()   # barcha

5.  def yarat(data: dict)   # validatsiyasiz
Javoblar
python
1.  parol_hash=bcrypt.hash(parol)

2.  os.environ["JWT_KALIT"] (.env)

3.  def vazifalar(user=Depends(joriy_user))

4.  Task.query.filter(user_id=user.id)

5.  def yarat(vazifa: TaskYarat)

Vazifa 3: Qatlamlar

Modellang:

  1. main/models
  2. schemas
  3. routers
  4. auth

Vazifa 4: Parol hash

Modellang:

  1. Hash
  2. Saqlash
  3. Tekshirish
  4. Xavfsizlik

Vazifa 5: JWT

Modellang:

  1. Token yarat
  2. Tekshir
  3. Soxta
  4. Holatsiz

Vazifa 6: Ruxsat

Modellang:

  1. Foydalanuvchi
  2. Filtr
  3. O'ziniki
  4. Xavfsizlik

Vazifa 7: O'ylash

REST API loyihasida xavfsizlik (parol hash, token, ruxsat) markaziy — bir xato butun tizimni xavf ostiga qo'yadi. Nima uchun xavfsizlik "keyingi qo'shiladigan xususiyat" emas, balki dizaynning boshidan o'ylanishi kerak (security by design), va nega "ishlaydi" bilan "xavfsiz ishlaydi" o'rtasida katta farq bor?

Javob

Qisqa javob: Xavfsizlik boshidan o'ylanishi kerak (security by design), chunki: xavfsizlik kesib o'tuvchi (cross-cutting) — u bir joyda emas, butun tizim bo'ylab (har endpoint, har so'rov, har ma'lumot); keyin qo'shish qiyin (arxitektura xavfsizlikni hisobga olmagan bo'lsa — qayta qurish kerak) va xatoga moyil (bir joy unutiladi — teshik). Boshidan o'ylansa: xavfsizlik arxitekturaga singdiriladi (har qatlam — auth, validatsiya, ruxsat), keyingi qo'shishdek emas. "Nega keyingi xususiyat emas": (1) kesib o'tuvchi — xavfsizlik hamma joyda (bir endpoint himoyasiz — butun tizim xavf); keyin qo'shish har joyni qayta ko'rish (qiyin, unutiladi); (2) zanjir eng zaif bo'g'in — bir teshik yetadi (99 endpoint himoyalangan, 1 yo'q — hujum o'shandan); xavfsizlik to'liq bo'lishi kerak (qisman emas); (3) qayta qurish qimmat — xavfsizliksiz qurilgan tizimni himoyalash — arxitektura o'zgarishi (qimmat, xatoli); boshidan arzon; (4) ishonch — xavfsizlik buzilsa, foydalanuvchi ishonchi ketadi (ma'lumot o'g'irlandi — obro' zarari). "Nega 'ishlaydi' ≠ 'xavfsiz ishlaydi'": (a) ishlaydi — normal foydalanuvchi to'g'ri ishlatganda ishlaydi (baxtli yo'l); (b) xavfsiz ishlaydi — yovuz foydalanuvchi buzishga uringanda ham himoyalangan (hujum yo'li); (c) farq — "ishlaydi" hujumni hisobga olmaydi (parol ochiq — normal ishlaydi, lekin o'g'irlansa halokat), "xavfsiz" hisobga oladi (hash — o'g'irlansa ham himoya); (d) ko'pincha xavfsizlik teshigi normal ishlashda ko'rinmaydi (parol ochiq saqlansa — ilova ishlaydi, teshik yashirin — buzilguncha). Bu umumiy tamoyil: xavfsizlik (va sifat, ishonchlilik) — xususiyat emas, xususiyat (property — butun tizimning holati, qo'shib bo'lmaydi, singdiriladi); dizayndan o'ylanadi (keyin emas); "ishlaydi" past bar (baxtli yo'l), "xavfsiz/ishonchli ishlaydi" yuqori bar (hujum/xato yo'li). Muhandislik saboqlari: xavfsizlik kesib o'tuvchi (boshidan singdir, keyin qo'shma); zanjir eng zaif bo'g'in (to'liq, qisman emas); ishlaydi ≠ xavfsiz ishlaydi (hujum yo'lini o'yla); xavfsizlik ko'rinmas teshik (normal ishlashda yashirin); dizayndan xavfsizlik (security by design). REST API misolida: parol hash, token, ruxsat — boshidan (arxitektura); keyin qo'shish — teshiklar, qayta qurish.

1. Nega boshidan (keyingi xususiyat emas)

  • Kesib o'tuvchi (butun tizim — har endpoint)
  • Zanjir eng zaif bo'g'in (bir teshik yetadi)
  • Qayta qurish qimmat (arxitektura o'zgarishi)
  • Ishonch (buzilsa — obro' zarari)

2. Nega "ishlaydi" ≠ "xavfsiz ishlaydi"

  • Ishlaydi — normal foydalanuvchi (baxtli yo'l)
  • Xavfsiz — yovuz foydalanuvchi ham (hujum yo'li)
  • "Ishlaydi" hujumni hisobga olmaydi (parol ochiq)
  • Teshik normal ishlashda ko'rinmaydi (yashirin)

3. Ishlaydi vs xavfsiz

Jihat Ishlaydi Xavfsiz ishlaydi
Foydalanuvchi Normal Normal + yovuz
Yo'l Baxtli Hujum ham
Parol ochiq Ishlaydi Halokat

4. Umumiy tamoyil

Xavfsizlik — xususiyat (property, singdiriladi). Dizayndan o'ylanadi. "Xavfsiz ishlaydi" yuqori bar.

5. Muhandislik saboqlari

  1. Xavfsizlik kesib o'tuvchi (boshidan singdir)
  2. Zanjir eng zaif bo'g'in (to'liq)
  3. Ishlaydi ≠ xavfsiz ishlaydi (hujum yo'li)
  4. Xavfsizlik ko'rinmas teshik (yashirin)
  5. Security by design (dizayndan)

6. Xulosa

  1. Xavfsizlik boshidan (kesib o'tuvchi, keyin qiyin)
  2. Bir teshik yetadi (to'liq bo'lsin)
  3. Ishlaydi ≠ xavfsiz (hujum yo'lini o'yla)
  4. REST API — hash, token, ruxsat (boshidan)

Nimani mustahkamlaydi: 2.4, 2.7-bo'limlar.


Xulosa

Bu darsda to'liq REST API loyihasini o'rgandik.

Eng muhim uch fikr:

  1. Tuzilish va API qatlami. REST API loyiha tuzilishi — qatlamli backend: main.py (FastAPI), models.py (ORM — User, Task), schemas.py (Pydantic — validatsiya), auth.py (JWT, hash), routers/ (endpoint), alembic/ (migratsiya); har qatlam bir vazifa (ajratish 27-qism). API qatlami (FastAPI): APIRouter (endpoint guruhi), @router.post (metod+yo'l), Pydantic (TaskYarat so'rov/TaskJavob javob — avtomatik validatsiya), Depends (bog'liqlik — auth, sessiya); avtomatik hujjat (Swagger).

  2. Baza, auth va himoya. Baza (ORM — SQLAlchemy): model (class User(Base) — jadval→klass, Column), ForeignKey (bog'lanish — Task→User), CRUD (session), doimiy saqlash. Autentifikatsiya (JWT): parol hash (bcrypt — ochiq saqlanmaydi), JWT token (user_id ichida, imzolangan — soxtalashtirib bo'lmaydi), holatsiz (server token'dan biladi). Himoyalangan endpointlar (Depends): joriy_user (token'dan User, xato→401), Depends(joriy_user) (endpoint himoya — qayta ishlatiladi); foydalanuvchi faqat o'zinikini (user.id).

  3. Xavfsizlik va backend ishi. Xavfsizlik va migratsiya: parol hash, maxfiy kalit .env (commit emas — CLAUDE.md), token muddati (exp), ruxsat (o'ziniki), ORM (SQL in'ektsiya oldini), Alembic (migratsiya — sxema o'zgarishi). REST API — backend dasturchining asosiy ishi (deyarli har ilova ortida — foydalanuvchi, auth, CRUD); uch qatlamni birlashtiradi (API+baza+auth), 23-qism to'liq amaliyoti; portfolioda kuchli (ishga tayyor). Xavfsizlik boshidan o'ylanadi (security by design — kesib o'tuvchi, keyin qiyin); "ishlaydi" ≠ "xavfsiz ishlaydi" (hujum yo'lini o'ylash).

Keyingi darsda Loyiha 3 — ma'lumot quvuri (ETL) ni quramiz: manba'dan ma'lumot olib (Extract), tozalab/o'zgartirib (Transform), maqsadga yozish (Load) — ma'lumot muhandisligi (data engineering) ning asosiy amaliyoti.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!