FastAPI gir utviklere muligheten til å lage API-er som både er raske og enkle å bruke. Når det gjelder å bygge dynamiske skjemaer som kan tilpasses basert på input fra brukeren, er det flere teknikker som kan brukes for å sikre at både frontend og backend samarbeider sømløst.
En av de mest praktiske metodene for å generere dynamiske skjemaer er å bruke FastAPI’s Pydantic-skjemaer. På baksiden kan et FastAPI-endepunkt returnere skjemaets struktur i JSON-format, som frontend kan bruke til å bygge HTML-skjemaet. Dette sikrer at eventuelle endringer i skjemaet på baksiden automatisk reflekteres på frontend, uten at man trenger å endre noe i HTML-koden.
Et eksempel på hvordan man kan lage et slikt endepunkt, som returnerer skjemaets struktur, ser slik ut:
Dette endepunktet genererer et standard JSON Schema-dokument som beskriver alle feltene, typene og metadataene for skjemaet. Frontend kan deretter bruke dette dokumentet til å dynamisk bygge HTML-inputfeltene.
Når man begynner å bygge skjemaet på frontend, kan man hente denne skjema-strukturen via JavaScript. Deretter kan man analysere JSON-skjemaet og generere de nødvendige HTML-inputfeltene basert på felttypene som er definert i Pydantic-modellen. Et enkelt eksempel på hvordan man kan gjøre dette, kan se slik ut:
Dette kan være en veldig enkel, men kraftig løsning for å bygge dynamiske skjemaer. Skjemaet vil automatisk tilpasse seg basert på endringer i backend Pydantic-modellen, og man slipper å gjøre manuelle endringer i HTML-koden.
En annen viktig funksjon er muligheten til å bruke betinget synlighet for enkelte skjemaelementer. For eksempel, hvis en bruker krysser av for et abonnement på et nyhetsbrev, kan man bruke JavaScript til å vise et ekstra felt for frekvensen på nyhetsbrevet. Dette kan gjøres ved å lytte etter endringer i et bestemt inputfelt og deretter vise eller skjule andre felter i skjemaet dynamisk:
Dette sikrer at skjemaet umiddelbart tilpasser seg brukernes valg, uten at det er behov for å laste inn siden på nytt.
Når skjemaet er ferdig utfylt og brukeren sender inn dataene, samler man inn alle verdiene fra feltene, inkludert de som kan være betinget synlige. Disse dataene sendes så til backend via et annet FastAPI-endepunkt, der Pydantic-skjemaet validerer dataene før de blir lagret eller behandlet. Eksemplet nedenfor viser hvordan man kan håndtere skjemaets innsending på frontend:
Backend-endepunktet ser ut som følger:
Dette tilnærmingen er ekstremt fleksibel. Hvis det er behov for å legge til et nytt felt, kan man enkelt gjøre det ved å endre Pydantic-skjemaet. Frontend vil automatisk tilpasse seg uten at man trenger å gjøre noen endringer i HTML- eller JavaScript-koden. Dette gjør det veldig enkelt å utvikle og vedlikeholde komplekse skjemaer med flere felt, inndataenums eller betingede visningsregler.
I tillegg er det viktig å merke seg hvordan FastAPI håndterer validering av data. Etter at skjemaet er sendt inn, kan backend bruke samme Pydantic-modell for å validere dataene. Dette sikrer at alle nødvendige felter er fylt ut og at dataene har riktig format før de behandles.
En annen viktig funksjon som kan forbedre brukeropplevelsen, er tilpasning av feilmeldinger. FastAPI gir muligheten til å definere tilpassede feilmeldinger for HTTP-koder. Dette kan gjøres ved å opprette egne Jinja2-malverk som kan brukes til å vise spesifikke feilmeldinger til brukeren. Eksempelvis kan en 404-feil (ressurs ikke funnet) vises på en mer informativ måte ved å lage en tilpasset HTML-side som forklarer hva som har gått galt.
I FastAPI kan man bruke Jinja2-malverk for å rendere tilpassede feilmeldinger basert på HTTP-feilkodene. For eksempel kan man lage en mal for å vise en mer informativ feilmelding hvis en bruker prøver å få tilgang til en ressurs som ikke eksisterer:
Når en feil oppstår, kan FastAPI bruke denne malen til å vise en tilpasset feilmelding til brukeren. Dette gir en mer brukervennlig opplevelse, spesielt når det er behov for å informere brukeren om hvorfor en handling mislyktes.
Hvordan bygge og sikre Markdown-til-HTML pipeline for webapplikasjoner
Markdown har blitt en viktig standard for tekstformatering på web, og med et økende behov for fleksibilitet og sikkerhet, er det avgjørende å håndtere Markdown på en trygg og effektiv måte. I denne delen av boken vil vi se på hvordan vi kan bygge et sikkert og pålitelig system for å konvertere Markdown til HTML i en webapplikasjon ved hjelp av Python, og hvordan vi kan presentere dette innholdet i en nettside.
Først ser vi på et praktisk eksempel på hvordan vi kan bruke Python til å håndtere og vise Markdown-innhold. Vi begynner med å lage en funksjon som konverterer Markdown-tekst til HTML, og deretter bruker vi en ekstra funksjon for å sikre HTML-koden mot potensielt skadelige elementer, som JavaScript eller farlige HTML-attributter. Dette kan for eksempel være nyttig i tilfeller hvor brukere laster opp innhold via et tekstfelt i en webapplikasjon, som i profiler eller kommentarer. Ved å benytte Python-bibliotekene markdown-it-py og bleach, kan vi sikre at innholdet vårt forblir trygt, samtidig som vi bevarer de ønskede formatene.
Funksjonen markdown_to_html gjør først konverteringen fra Markdown til HTML, og deretter blir den resulterende HTML-koden "renset" gjennom funksjonen sanitize_html. Denne prosessen fjerner uønskede HTML-tagger og attributter, som kan inneholde skadelige skript. Resultatet er en trygg HTML-struktur som kan vises på nettsiden uten risiko for angrep som XSS (Cross-Site Scripting).
Når vi har renset HTML-en, kan vi bruke den videre i applikasjonen vår. For eksempel, i et FastAPI-basert webgrensesnitt, kan vi vise artikkelinformasjon som inneholder Markdown-tekst. Ved å kombinere funksjonene for konvertering og rensing, kan vi lage en pålitelig arbeidsflyt for å håndtere dynamisk innhold. FastAPI gir oss muligheten til å bruke Jinja2 som templatemotor, og her kan vi bruke den rensede HTML-en direkte i malene våre, samtidig som vi sikrer at den ikke blir gjenopprettet som ren tekst, takket være |safe-filteret i Jinja2.
Denne arbeidsflyten gjør det mulig å bygge applikasjoner som kan håndtere alt fra profiler til produktanmeldelser eller kommentarer på et forum, samtidig som vi holder systemet vårt sikkert og effektivt. Ved å bruke de riktige verktøyene for HTML-rensing og Markdown-konvertering, kan vi enkelt tilby en fleksibel og trygg løsning for å vise rik tekst på nettet.
Det er viktig å forstå at, til tross for at denne tilnærmingen sikrer at innholdet er trygt for visning, bør vi også være bevisste på hva som kan utløse sårbarheter. Selv om vi filtrerer bort mange skadelige elementer, er det alltid rom for forbedring i hvordan vi håndterer innhold som brukerne gir oss. Det er essensielt å være klar over at angrep kan komme i mange former, og en grundig gjennomgang av sikkerhetspraksis er alltid nødvendig.
En annen viktig faktor er hvordan innholdet vises etter at det er konvertert til HTML. Selv om vi har sikret Markdown-konverteringen, er det fortsatt viktig å sørge for at HTML-visningen i selve webapplikasjonen håndteres riktig. Bruken av |safe-filteret i Jinja2 er en god praksis for å unngå automatisk escaping av HTML-tagger, men vi må også være på vakt mot uforutsette sikkerhetshull som kan oppstå i frontend-koden. Det er viktig at vi gjennomfører grundige tester og bruker automatiserte sikkerhetsskanninger for å sikre at applikasjonen vår forblir robust og beskyttet.
En annen betraktning er ytelse. Når vi jobber med store datamengder, som lange artikler eller kommentarer med mye Markdown-innhold, må vi sørge for at systemet vårt er effektivt nok til å håndtere konverteringen raskt. Bruken av asynkrone endepunkter i FastAPI hjelper til med å minimere blokkering av prosesser, men det er også viktig å vurdere andre optimaliseringer, som caching, spesielt hvis vi har innhold som ikke endres ofte.
Avslutningsvis er det viktig å erkjenne at verktøyene og teknikkene vi har sett på i denne delen, kan brukes til mye mer enn bare å vise Markdown-innhold på en nettside. De kan også benyttes til å håndtere filer som CSV, Excel eller PDF, og kan være en del av et større system for behandling og visning av innhold på en webapplikasjon.
Endtext
Hvordan sikre API-er med CSRF, CORS og CSP i FastAPI
For å beskytte applikasjoner mot ulike typer angrep er det viktig å forstå hvordan sikkerhet kan implementeres effektivt på servernivå. I denne sammenhengen ser vi på hvordan man kan bruke CSRF-beskyttelse (Cross-Site Request Forgery), CORS (Cross-Origin Resource Sharing) og CSP (Content Security Policy) i FastAPI, et populært Python-rammeverk for utvikling av webapplikasjoner.
Når det gjelder CSRF, er det en angrepsmetode som utnytter at en autentisert bruker kan utføre uønskede handlinger på en nettside uten deres samtykke. Dette kan forhindres ved å bruke CSRF-beskyttelse, hvor serveren genererer en hemmelig token som klienten må sende med i sine forespørsler. For alle forespørsler som kan endre tilstanden til serveren (som POST, PUT, PATCH eller DELETE), er det nødvendig at klienten sender en gyldig CSRF-token.
I FastAPI kan man implementere CSRF-beskyttelse gjennom et middelvare- og avhengighetsmønster. Når klienten sender en POST-forespørsel til for eksempel /account/update, vil serveren validere CSRF-tokenen som følger med forespørselen. Dersom tokenen er gyldig, kan serveren fortsette med behandlingen av forespørselen; hvis ikke, blokkeres den.
CORS-politikk er et annet viktig sikkerhetsaspekt. CORS definerer hvilke domener som har tilgang til API-en vår. Ved å bruke FastAPI kan man spesifisere hvilke domener som har lov til å gjøre forespørsler til API-en. Dette forhindrer at ondsinnede nettsteder gjør API-kall på vegne av brukeren. For å strengt definere hvilke metoder og overskrifter som er tillatt, kan man bruke FastAPI-mellomvaren CORSMiddleware. Dette kan være nyttig for å begrense tilgangen til API-et til betrodde domener og for å sikre at sensitive data som cookies eller autentisering ikke lekker ut til ikke-betrodd kilder.
Preflight-forespørsler er en annen viktig komponent som må håndteres korrekt. Moderne nettlesere sender en preflight OPTIONS-forespørsel før en kryss-opprinnelse POST, PUT eller DELETE forespørsel blir sendt. Dette gir serveren muligheten til å svare med hvilke metoder og overskrifter som er tillatt. FastAPI håndterer disse forespørslene automatisk via sin CORS-mellomvare, men det er viktig å være oppmerksom på hvordan serveren reagerer på disse forespørslene for å sikre at de nødvendige CORS-hodene blir sendt.
Når det gjelder testing av CSRF og CORS, kan man bruke verktøy som curl eller nettleserens utviklerverktøy for å simulere forespørslene og verifisere at beskyttelsen fungerer som den skal. En vanlig feil kan være at CORS-politikken er feil konfigurert, eller at CSRF-tokenene ikke blir sendt riktig, noe som resulterer i at serveren blokkerer forespørselen.
Til slutt er det viktig å nevne Content Security Policy (CSP) som et viktig verktøy for å forhindre XSS-angrep og andre sikkerhetstrusler. CSP tillater utviklere å spesifisere hvilke kilder som er tillatt for innhold som JavaScript, CSS, bilder og andre ressurser. Ved å bruke strenge CSP-innstillinger kan man redusere angrepsflaten ved å blokkere innhold fra ikke-betrodd opprinnelse. FastAPI gjør det enkelt å implementere CSP-hoder ved hjelp av egendefinerte mellomvare-løsninger.
Når man designer en streng CSP-politikk, bør man starte med å tillate kun det som er absolutt nødvendig. Det kan være lurt å begynne med å nekte all ekstern ressursbruk og gradvis tillate betrodde kilder. For eksempel kan man spesifisere at kun JavaScript og CSS fra samme opprinnelse er tillatt, og at bilder kun kan lastes fra bestemte URL-er.
Å sikre API-er på riktig måte krever en grundig forståelse av de ulike teknologiene som beskytter mot angrep. CSRF, CORS og CSP spiller alle en viktig rolle i å beskytte både brukernes data og applikasjonens integritet. Ved å implementere disse beskyttelsene i et FastAPI-baserte system kan man sørge for at applikasjonen er godt rustet mot vanlige angrep.
Hvordan bygge pålitelig programvare med CI/CD, testing og Docker
Integrasjonstester er en viktig del av utviklingsprosessen for å sikre at hele applikasjonen fungerer som forventet når de forskjellige komponentene samarbeider. I testingens verden skiller man mellom enkle enhetstester og mer omfattende integrasjonstester som simulerer reelle scenarioer. En viktig del av dette arbeidet er å verifisere at ikke bare enkeltstående API-endepunkter fungerer, men at hele arbeidsflyter og integrasjoner mellom ulike systemer gir de ønskede resultatene. I denne sammenhengen kan Docker og GitHub Actions bidra til å gjøre testene mer pålitelige og sikre at programvaren utvikles i henhold til de høyeste standardene.
For eksempel, når man tester en serie med API-kall som krever autentisering og interaksjon med Redis, må man sørge for at hvert trinn i arbeidsflyten fungerer korrekt. Dette kan innebære at man først registrerer en bruker, deretter logger inn, og til slutt lagrer og henter en verdi i Redis som en autentisert bruker. Alle disse trinnene må verifiseres i en reell integrasjonstest som bruker de samme systemene som ville blitt brukt i produksjon.
For å gjennomføre slike tester effektivt, er det viktig å sette opp et testmiljø som speiler produksjonen. Dette kan gjøres ved hjelp av Docker, som lar deg kjøre alle nødvendige tjenester, som Redis, i et isolert miljø, noe som gjør det enklere å teste hele applikasjonen på en pålitelig måte. Docker Compose kan også brukes for å orkestrere disse tjenestene, og dermed sikre at alle avhengigheter blir kjørt på riktig måte i testene.
GitHub Actions er et utmerket verktøy for å automatisere testene og CI/CD-pipelinen. Med GitHub Actions kan man definere arbeidsflyter som kjøres automatisk når koden pushes til repositoryet, enten det er ved å opprette en pull request eller ved å gjøre en commit direkte til hovedgrenen. I en typisk CI/CD-pipeline kan man inkludere trinn for å sjekke koden for stilfeil ved hjelp av lintere som flake8, kjøre enhetstester og integrasjonstester, bygge Docker-bilder, og til slutt pushe bildene til en Docker-registry, som for eksempel DockerHub.
En viktig del av en CI/CD-pipeline er at den gir kontinuerlig tilbakemelding om kvaliteten på koden. Dette hjelper utviklerne med å få umiddelbar tilbakemelding om eventuelle problemer som kan ha blitt introdusert i koden. Det er også viktig å overvåke testdekning for å sikre at alle deler av koden blir testet. Testdekning viser hvilke deler av applikasjonen som er dekket av tester og hvilke som ikke er det. Dette kan være nyttig for å identifisere potensielle problemer og for å holde testene relevante i forhold til den faktiske koden som utvikles.
I tillegg til å teste funksjonalitet, kan det også være viktig å teste at systemet er i stand til å håndtere feil på en god måte. Det er ikke bare de lykkede testene som gir verdi, men også de som simulerer feil og uventede situasjoner. Dette kan inkludere feilhåndtering i APIene, sjekk av loggutdata, og verifisering av om systemet oppfører seg riktig når eksterne tjenester ikke er tilgjengelige.
Gjennom å bruke GitHub Actions kan man også legge til ekstra funksjoner som varsler når tester feiler, for eksempel gjennom Slack eller e-post. Dette kan være svært nyttig for å holde teamet informert om eventuelle problemer som kan ha oppstått under testene, og kan bidra til å få problemer løst raskere.
For å bygge en robust og pålitelig programvareplattform er det avgjørende å ha en strukturert og automatisert tilnærming til testing og distribusjon. Med verktøy som Docker og GitHub Actions får man et pålitelig testmiljø som kan tilpasses etter behov. Dette gir både utviklere og team den nødvendige tilliten til at programvaren fungerer som den skal, uavhengig av hvilke endringer som blir gjort i koden.
En annen viktig faktor er at utviklingsprosessen bør være transparent. Med CI/CD-pipelines kan alle endringer og resultater dokumenteres automatisk, noe som gjør det lettere for teamet å spore hvordan programvaren utvikler seg over tid. Denne dokumentasjonen er også et viktig verktøy for å identifisere svakheter eller forbedringsområder i koden, samt for å holde oversikt over hvilke versjoner som er utgitt og deployert til ulike miljøer.
Det er viktig å forstå at CI/CD og testing ikke bare er noe som skjer én gang i utviklingsprosessen, men noe som må integreres kontinuerlig for å sikre at programvaren forblir stabil og funksjonell under hele utviklingen. Testene bør kjøres regelmessig, og tilbakemeldingene fra disse testene bør tas på alvor for å kontinuerlig forbedre applikasjonen.

Deutsch
Francais
Nederlands
Svenska
Norsk
Dansk
Suomi
Espanol
Italiano
Portugues
Magyar
Polski
Cestina
Русский