Python Academy · Oppitunti

Riippuvuuksien injektointi ja todentaminen

Käyttäkää FastAPI:n DI-järjestelmää jaettuun logiikkaan ja JWT-pohjaiseen todennukseen.

Oppitunti 3/413 vaihetta

Riippuvuuksien injektointi ja todentaminen on ilmainen Python Academy-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Python Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Python Academy-kurssilla on yhteensä 4 oppituntia.

Mitä riippuvuuksien injektointi on?

FastAPIssa Depends() mahdollistaa jaetun logiikan, kuten tietokantaistuntojen, todennustarkistusten ja asetusten, määrittämisen siten, että se injektoidaan automaattisesti reittikäsittelijöihin.

from fastapi import FastAPI, Depends
app = FastAPI()

def get_db():
    db = connect_db()
    try: yield db
    finally: db.close()

@app.get("/users")
def list_users(db = Depends(get_db)):
    return db.query_all("users")

Riippuvuusfunktiot

Riippuvuus voi olla mikä tahansa kutsuttava objekti. Se voi olla funktio, luokka tai toinen riippuvuuksia käyttävä funktio.

from fastapi import Depends, FastAPI
app = FastAPI()

def common_params(skip: int = 0, limit: int = 10):
    return {"skip": skip, "limit": limit}

@app.get("/items")
def list_items(params: dict = Depends(common_params)):
    return params

@app.get("/users")
def list_users(params: dict = Depends(common_params)):
    return params

Luokkariippuvuudet

Käyttäkää luokkaa riippuvuutena toisiinsa liittyvien asetusten ryhmittelemiseen. Luokkaa kutsutaan siten, että sen __init__-argumentit injektoidaan automaattisesti.

from fastapi import Depends, FastAPI, Query
app = FastAPI()

class Pagination:
    def __init__(self, page: int = Query(1,ge=1), size: int = Query(10,ge=1,le=100)):
        self.page = page
        self.size = size
        self.offset = (page - 1) * size

@app.get("/items")
def list_items(pag: Pagination = Depends()):
    return {"offset": pag.offset, "size": pag.size}

OAuth2 Password Bearer

Käyttäkää OAuth2PasswordBearer-luokkaa Bearer-tokenin lukemiseen Authorization-otsakkeesta.

from fastapi import FastAPI, Depends
from fastapi.security import OAuth2PasswordBearer
app = FastAPI()

oauth2 = OAuth2PasswordBearer(tokenUrl="/token")

@app.get("/me")
def me(token: str = Depends(oauth2)):
    return {"token": token}   # validate token here

JWT-tokenit

Luokaa ja tarkistakaa JWT-tokenit python-jose-kirjastolla (tai pyjwt-kirjastolla). Palauttakaa token kirjautumisen yhteydessä ja tarkistakaa se jokaisella suojatulla reitillä.

# pip install python-jose passlib
from jose import jwt, JWTError

SECRET_KEY = "change-me"
ALGORITHM = "HS256"

def create_token(data: dict) -> str:
    return jwt.encode(data, SECRET_KEY, algorithm=ALGORITHM)

def verify_token(token: str) -> dict:
    return jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])

Nykyisen käyttäjän riippuvuus

Rakentakaa get_current_user-riippuvuus, joka tarkistaa JWT-tokenin ja palauttaa todennetun käyttäjän.

from fastapi import Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
from jose import jwt, JWTError

oauth2 = OAuth2PasswordBearer(tokenUrl="/token")

def get_current_user(token: str = Depends(oauth2)):
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
        return payload["sub"]
    except JWTError:
        raise HTTPException(status_code=401, detail="Invalid token")

# @app.get("/me")
# def me(user=Depends(get_current_user)): return user

Salasanojen hajauttaminen

Älkää koskaan tallentako selväkielisiä salasanoja. Käyttäkää passlib-kirjastoa salasanojen hajauttamiseen bcryptillä.

from passlib.context import CryptContext

pwd_ctx = CryptContext(schemes=["bcrypt"], deprecated="auto")

def hash_pw(plain: str) -> str:
    return pwd_ctx.hash(plain)

def verify_pw(plain: str, hashed: str) -> bool:
    return pwd_ctx.verify(plain, hashed)

Token-päätepiste

Toteuttakaa POST /token, joka vastaanottaa lomaketunnistetiedot, tarkistaa salasanan ja palauttaa JWT-tokenin.

from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordRequestForm
app = FastAPI()

@app.post("/token")
def login(form: OAuth2PasswordRequestForm = Depends()):
    user = get_user_by_username(form.username)
    if not user or not verify_pw(form.password, user.hashed_pw):
        raise HTTPException(status_code=401, detail="Bad credentials")
    token = create_token({"sub": form.username})
    return {"access_token": token, "token_type": "bearer"}

API-avaimen todennus

Yksinkertaisemmissa tapauksissa validoikaa API-avain otsakkeesta tai kyselyparametrista.

from fastapi import Depends, HTTPException, Security
from fastapi.security import APIKeyHeader

API_KEY_HEADER = APIKeyHeader(name="X-API-Key")

def require_api_key(key: str = Security(API_KEY_HEADER)):
    if key != "secret-key":
        raise HTTPException(status_code=403, detail="Forbidden")
    return key

Roolipohjainen käyttöoikeuksien hallinta

Laajentakaa todennusta käyttöoikeuksilla lisäämällä roolitarkistukset riippuvuuksiin.

from fastapi import Depends, HTTPException

def require_admin(user=Depends(get_current_user)):
    if user.get("role") != "admin":
        raise HTTPException(status_code=403, detail="Admins only")
    return user

# @app.delete("/users/{uid}")
# def delete_user(uid: int, admin=Depends(require_admin)):

Riippuvuuksien välimuisti

Oletusarvoisesti riippuvuus kutsutaan kerran pyyntöä kohden, ja sen tulos jaetaan kaikkien kyseisen pyynnön aikana sitä käyttävien reittien kesken.

# The same db session object is shared:
@app.get("/summary")
def summary(
    db = Depends(get_db),      # db resolved once
    stats = Depends(get_stats) # get_stats also uses get_db — same db instance
): ...

Pikatarkistus

Mitä Depends() tekee FastAPIssa?

Kertaus

Injektoikaa jaettu logiikka käyttämällä Depends(func)-riippuvuutta. Rakentakaa todennus käyttäen OAuth2PasswordBearer-komponenttia, JWT-tunnuksia ja get_current_user-riippuvuutta. Tiivistäkää salasanat passlibillä/bcryptillä. Lisätkää roolitarkistukset uusina riippuvuuksina.

Aloita maksutta

Opi Python tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
76
Oppitunnit
320

Usein kysytyt kysymykset

Onko oppitunti ”Riippuvuuksien injektointi ja todentaminen” ilmainen?

Kyllä – oppitunnin ”Riippuvuuksien injektointi ja todentaminen” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Python Academy-kurssin, päivitä CoddyKit PROhon. Python Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Riippuvuuksien injektointi ja todentaminen”?

Käyttäkää FastAPI:n DI-järjestelmää jaettuun logiikkaan ja JWT-pohjaiseen todennukseen. Harjoittelet Python Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Python Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Python Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.

Kuinka kauan ”Riippuvuuksien injektointi ja todentaminen”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Python Academy-oppitunnilla?

Kyllä. Jokainen Python Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. FastAPI-projektin määritys ja ensimmäinen päätepiste
  2. Polkuparametrit, kyselyparametrit ja pyyntörungot
  3. Riippuvuuksien injektointi ja todentaminen
  4. Asynkroniset päätepisteet ja tietokantaintegraatio
← Takaisin: Python Academy