Ga naar hoofdinhoud

Invoer controleren: in de praktijk

Met de grenzen in Form en je eigen controles uit les 3 tot en met 8 bewaak je één formulier. Een echte site doet dat overal, en op een vaste manier.

Wat jij zelf doet​

Toestaan wat mag, niet weren wat niet mag​

Je kunt opsommen wat níét mag, of opsommen wat wél mag. Het tweede is veiliger.

Neem een gebruikersnaam. Weren wat niet mag ("geen <, geen spaties, geen ;…") laat altijd iets door dat je niet bedacht had. Toestaan wat mag ("alleen letters en cijfers, 3 tot 20 tekens") laat precies dat door en de rest niet. In FastAPI is dat een grens in Form en één if in je functie:

@app.post("/profiel")
async def profiel_opslaan(naam: str = Form(..., min_length=3, max_length=20)):
if not naam.isalnum():
raise HTTPException(status_code=400, detail="Alleen letters en cijfers")

min_length is de ondergrens, net als max_length de bovengrens. isalnum() is waar als een tekst alleen uit letters en cijfers bestaat, zonder spaties. Wat je vergeet te noemen, is dan geweigerd in plaats van toegestaan. Dat is hetzelfde idee als de lijst met stemmingen uit les 7 en de pagina's uit les 8. Je komt het later weer tegen in Wie mag wat: in de praktijk, als deny by default.

Een 422 zegt genoeg​

FastAPI stuurt bij een te lang of ontbrekend veld een 422 met daarin welk veld het was en waarom. Dat is genoeg: de afzender weet wat hij moet aanpassen, en je verraadt niets gevoeligs. Bouw zelf geen uitgebreide foutmeldingen die bijvoorbeeld tonen wat er wél in de database staat.

Wat grote sites nog meer doen​

Dit hoef je voor je eigen project niet te bouwen. Klap open wat je wilt lezen.

Een grens op de grootte van een verzoek

max_length bewaakt één veld. Starlette, het deel van FastAPI dat formulieren leest, weigert zelf al een veld boven een megabyte; dat zag je in les 2. Een verzoek kan ook op andere manieren groot zijn: een enorm geüpload bestand, of duizend velden tegelijk. Daar zet je een grens omheen die vóór je code komt. Dat regel je meestal niet in FastAPI zelf, maar in een server ervoor, zoals nginx. Wat zo'n server ervoor doet, lees je later in Te veel verzoeken: in de praktijk. In nginx is de grens één regel:

client_max_body_size 1m;

Alles groter dan een megabyte weigert nginx dan, voordat het je server bereikt.

Opdracht: welke aanpak past?​

Kies bij elke situatie de aanpak uit deze reeks die past.

  1. Een veld voor een leeftijd krijgt de tekst honderd binnen.
  2. Iemand uploadt een bestand van 2 gigabyte naar je server.
  3. Je wilt een gebruikersnaam toestaan, maar geen rare tekens.
  4. Een bezoeker kiest met ?naam= welke pagina je server stuurt.
Antwoord
  1. Type in de parameter: leeftijd: int = Form(...). FastAPI weigert honderd dan met een 422, net als het cijfer in les 6. Met ge en le zet je er ook een onder- en bovengrens op.
  2. Een grens op de grootte van het verzoek, in de server vóór FastAPI.
  3. Toestaan wat mag: min_length en max_length in Form, en een 400 als isalnum() niet waar is.
  4. Een lijst met de pagina's die mogen, zoals in les 8. Een naam die er niet in staat, krijgt een 404 voordat FileResponse iets opent.

Door naar de volgende reeks: HTML van een bezoeker.