🔌 API ceļvedis - projektēšana, drošība un infrastruktūra
Sešas sadaļas par lietojumprogrammu saskarnēm (API) atbilstoši starptautiskajai praksei: REST principi (Roy Fielding, 2000), HTTP metodes un statusa kodi (RFC 9110), drošība (OWASP API Top 10, OAuth 2.0, JWT), API vārtejas, reverse proxy un slodzes balansētāja atšķirības, dizaina prakses (RFC 9457, OpenAPI 3.1) un standartu atsauces. Piemēri ir izdomāti, paredzēti mācībām.
Kas ir API
REST arhitektūras stils - Roy Fielding (2000)
API (Application Programming Interface) ir vienošanās starp divām programmām par to, kā tās apmainās ar datiem. Tīmekļa API parasti balstās uz HTTP protokolu un REST arhitektūras stilu: resursus adresē ar URL, darbības izsaka ar HTTP metodēm, bet dati visbiežāk tiek pārraidīti JSON formātā.
Klients–serveris
Klients (tas, ko redz lietotājs) ir atdalīts no servera (dati un loģika), tāpēc abus var izstrādāt un mērogot neatkarīgi.
Bezstāvokļa
Katrs pieprasījums satur visu izpildei nepieciešamo kontekstu. Serveris neuztur klienta sesijas stāvokli, kas vienkāršo horizontālo mērogošanu.
Kešojamība
Katra atbilde skaidri pasaka, vai to drīkst kešot (Cache-Control, ETag) - tas samazina servera slodzi un atbildes laiku.
Vienota saskarne
Vienoti mijiedarbības principi: resursu identifikācija, to attēlojumi (piem., JSON), pašaprakstoši ziņojumi un hipersaites (HATEOAS).
Slāņota sistēma
Starp klientu un serveri var atrasties starpniekslāņi (reverse proxy, gateway, kešs), klientam par tiem nezinot.
Kods pēc pieprasījuma
Neobligāts princips: serveris var nosūtīt izpildāmu kodu (piem., JavaScript), īslaicīgi paplašinot klienta funkcionalitāti.
Viens API pieprasījums soli pa solim
Kas notiek starp klientu, serveri un datubāzi - un kur jābūt drošības pārbaudēm.
Pieprasījums uz API
- 1Klients → APIGET /rekini/42Authorization: Bearer …
Klients prasa rēķinu Nr. 42 un pievieno piekļuves tokenu.
- 2APIpārbauda tokenu: paraksts, izdevējs, termiņš → lietotājs = Anna
Autentifikācija: serveris noskaidro, kas jautā. Nederīgs tokens → 401.
- 3APIvai rēķins 42 pieder Annai?
Autorizācija: tieši šīs pārbaudes trūkums ir biežākais API risks (BOLA) - mainot numuru, var redzēt svešus rēķinus.
- 4API → DatubāzeSELECT … WHERE id = 42 AND owner = Anna
Vaicājums ar parametriem un īpašnieka nosacījumu - nevis ar lietotāja tekstu, kas ielīmēts SQL.
- 5Datubāze → API1 rinda
Datubāze atgriež ierakstu vai neko.
- 6API → Klients200 OK + JSON
Ja rēķins nav Annai, atbilde ir 404, ne 403 - lai neatklātu, ka tāds rēķins vispār pastāv.
REST
Resursorientēts arhitektūras stils virs HTTP. Vienkāršs un kešojams. Dominē publiskajos tīmekļa API.
GraphQL
Viens endpoint. Klients pieprasa tieši nepieciešamos laukus. Mazina pārmērīgu un nepietiekamu datu ielādi.
gRPC
Binārs, augstas veiktspējas RPC ietvars (Protocol Buffers, HTTP/2). Piemērots iekšējai mikroservisu saziņai.
WebSocket / SOAP
WebSocket - pastāvīgs divvirzienu reāllaika kanāls. SOAP - vecāks XML protokols ar stingri definētu līgumu (WSDL).
RFC 9110 - HTTP Semantics
Metodes (droša / idempotent) un statusa kodi
| Metode | Droša | Idempotent | Kešojama | Tipiskais pielietojums |
|---|---|---|---|---|
| GET | ✔ | ✔ | ✔ | Nolasa resursu bez blakusefektiem |
| HEAD | ✔ | ✔ | ✔ | Atgriež tikai galvenes, bez ķermeņa |
| POST | ✗ | ✗ | reti | Izveido resursu vai palaiž darbību |
| PUT | ✗ | ✔ | ✗ | Pilnībā aizvieto resursu |
| PATCH | ✗ | ✗ | ✗ | Daļēji atjaunina resursu |
| DELETE | ✗ | ✔ | ✗ | Dzēš resursu |
| OPTIONS | ✔ | ✔ | ✗ | Atbalstītās metodes. CORS priekšpārbaude |
Droša (safe)
Nemaina servera stāvokli. Tikai nolasa datus. GET, HEAD, OPTIONS.
Idempotent
Ja to pašu pieprasījumu atkārto, rezultāts ir tāds pats kā pēc viena izsaukuma. Tas ļauj droši atkārtot pieprasījumu pēc tīkla kļūmes.
POST nav idempotent
Atkārtots POST var radīt dublikātus. Risinājums - Idempotency-Key galvene (skat. sadaļu Dizaina prakses).
OWASP API Security Top 10:2023, OAuth 2.0, JWT
Autentifikācija, autorizācija un izplatītākie API riski
API drošības pamatā ir skaidra autentifikācijas (identitātes apliecināšana) un autorizācijas (piekļuves tiesību noteikšana) nošķiršana. Tīmeklī standarta risinājums ir OAuth 2.0 ar piekļuves tokeniem (parasti JWT), kurus pārbauda katrā pieprasījumā.
OAuth 2.0 ar PKCE soli pa solim
Četras puses: lietotājs, lietotne, autorizācijas serveris un API. Lietotne paroli neredz nekad.
OAuth 2.0 ar PKCE
- 1Lietotneizveido nejaušucode_verifierun tā jaucējvērtībucode_challenge
Lietotne sagatavo vienreizēju noslēpumu. Tā jaucējvērtību drīkst rādīt, pašu noslēpumu - nē.
- 2Lietotne → Autorizācijas serverispāradresācija + code_challenge
Lietotne caur pārlūku nosūta lietotāju uz autorizācijas serveri.
- 3Lietotājs → Autorizācijas serverispieteikšanās un piekrišana
Lietotājs piesakās tieši autorizācijas serverī - lietotne viņa paroli neredz.
- 4Autorizācijas serveris → Lietotnevienreizējs code
Serveris caur pārlūku atdod īslaicīgu kodu. Šo soli var pārtvert - tāpēc vajag PKCE.
- 5Lietotne → Autorizācijas serveriscodecode_verifier
Lietotne apmaina kodu, pievienojot sākotnējo noslēpumu. Serveris pārbauda, ka tā jaucējvērtība sakrīt ar code_challenge.
- 6Autorizācijas serveris → Lietotneaccess token (JWT, īss termiņš)refresh token
Pārtvērējam ar kodu vien nepietiek - bez code_verifier tokenu viņš nesaņem.
- 7Lietotne → APIGET /resurss + Bearer token
Lietotne izsauc API. API pārbauda tokena parakstu, adresātu (aud) un termiņu (exp) un tad atbild.
API atslēgas
Vienkārša servisa identifikācija. Nedrīkst nonākt klienta pusē vai koda repozitorijā. Regulāri jāmaina (rotācija).
OAuth 2.0 / OIDC
Deleģēta autorizācija ar tokeniem. OIDC papildina to ar identitātes slāni. RFC 9700 (2025): PKCE visiem klientiem, netiešā (implicit) un paroles plūsma netiek lietota.
JWT
Kriptogrāfiski parakstīts tokens trīs daļās: header.payload.signature. Vienmēr jāpārbauda paraksts ar iepriekš noteiktu algoritmu (alg: none noraida), izdevējs (iss), adresāts (aud) un derīguma termiņš (exp) - RFC 8725.
mTLS
Abpusēja TLS - gan klients, gan serveris uzrāda sertifikātus. Spēcīga savstarpējā autentifikācija starp servisiem.
BOLA
Objektu līmeņa autorizācijas trūkums - lietotājs piekļūst cita subjekta objektam, manipulējot ar identifikatoru (piem., /rekini/123). Visbiežākais API risks.
Nepilnīga autentifikācija
Vāji vai nepareizi pārbaudīti tokeni, nepārbaudīts paraksts, neierobežots pieteikšanās mēģinājumu skaits.
BOPLA
Objektu īpašību līmeņa autorizācijas trūkums - pārmērīga datu atklāšana atbildē vai neatļauta masveida piešķiršana (mass assignment).
Neierobežots resursu patēriņš
Trūkst apjoma un ātruma limitu - tas pieļauj pakalpojuma atteices (DoS) un infrastruktūras izmaksu pieaugumu.
BFLA
Funkciju līmeņa autorizācijas trūkums - parasts lietotājs piekļūst administratīvām funkcijām.
Jutīgas biznesa plūsmas
Neierobežota piekļuve jutīgām biznesa plūsmām - automatizēta ļaunprātīga izmantošana (piem., masveida biļešu uzpirkšana).
SSRF
Servera puses pieprasījumu viltošana - serveris izpilda pieprasījumu uz uzbrucēja kontrolētu URL, sasniedzot iekšējos resursus.
Drošības konfigurācijas trūkumi
Trūkstošas drošības galvenes, pārāk atvērts CORS, pārāk detalizēti kļūdu paziņojumi.
Nepietiekama inventāra pārvaldība
Aizmirstas vai novecojušas versijas un testa vides paliek publiski pieejamas un nedrošas.
Nedroša patērēšana
Akla uzticēšanās trešo pušu API datiem - bez pārbaudes un ierobežojumiem.
Infrastruktūra priekšā API
API vārteja vs reverse proxy vs slodzes balansētājs
Visi trīs atrodas starp klientu un backend, tāpēc tos mēdz sajaukt. Patiesībā visi ir reverse proxy paveidi, katrs specializējies savā darbā. Praksē to robežas pārklājas, un bieži tie darbojas vienlaikus.
| Aspekts | Reverse proxy | Slodzes balansētājs | API vārteja |
|---|---|---|---|
| Galvenais mērķis | Pārsūta pieprasījumus uz backend, slēpj tā topoloģiju | Sadala trafiku pa vairākām servera instancēm | Pārvalda API - vienots ieejas punkts mikroservisiem |
| OSI slānis | L7 (var arī L4) | L4 (transports) vai L7 | L7 (lietojums) |
| Maršrutē pēc | Host / ceļa | IP / ports (L4) vai saturs (L7) | API ceļa, versijas, patērētāja |
| TLS terminācija | Jā | Jā (L7) | Jā |
| Autentifikācija / autorizācija | Pamata (iespējams WAF) | Nē | Jā - OAuth / JWT / API atslēgas (galvenā loma) |
| Rate-limit / kvotas | Ierobežoti | Nē | Jā (galvenā loma) |
| Health checks | Reti | Jā (galvenā loma) | Bieži (caur balansētāju) |
| Transformācija / agregācija | Nē | Nē | Jā - REST↔gRPC, vairāku servisu apvienošana |
| Tipiski rīki | Nginx, Apache, HAProxy, Envoy | HAProxy, Nginx, AWS NLB/ALB, F5 | Kong, Apigee, AWS API Gateway, Azure APIM, Tyk |
Reverse proxy
Pamatkoncepts - serveris klienta priekšā, kas pārsūta pieprasījumus uz backend. Nodrošina TLS termināciju, kešošanu, kompresiju un topoloģijas slēpšanu. Pārējie divi ir tā specializācijas.
Slodzes balansētājs
Reverse proxy, kas specializējas trafika sadalē (round-robin, least-connections) un pieejamībā - ar health checks un sticky sesijām.
API vārteja
Reverse proxy, kas specializējas API pārvaldībā: autentifikācija, rate-limit, versionēšana, transformācija, agregācija un novērojamība. Parasti tā ietver arī slodzes balansēšanu.
Praksē
Tipiska secība: klients → DNS/CDN → slodzes balansētājs → API vārteja → mikroservisi. Robežas pārklājas, un viens rīks bieži pilda vairākas lomas.
Labās prakses, RFC 9457, OpenAPI 3.1
Versionēšana, limiti, kļūdas un līguma apraksts
Versionēšana
Pa URL (/v1/...), galveni vai mediju tipu. Esošo versiju saderību nedrīkst lauzt - jāpievieno jauna versija.
Pagination
Lielus sarakstus dala lapās ar offset/limit vai kursora metodi. Vienmēr jāierobežo maksimālais lapas apjoms.
Rate limiting
Pieprasījumu ātruma ierobežošana ar atbildi 429 Too Many Requests un Retry-After galveni. Aizsargā pret pārslodzi un ļaunprātīgu izmantošanu.
Idempotency-Key
Idempotency-Key galvene POST izsaukumos novērš dublikātus, ja pieprasījumu atkārto pēc tīkla kļūmes.
Vienots kļūdu formāts
RFC 9457 Problem Details - mašīnlasāma JSON kļūdas struktūra (type, title, status, detail).
OpenAPI 3.1
Mašīnlasāms API līgums - ģenerē dokumentāciju, klientu kodu un validāciju. Vienots patiesības avots saskarnei.
Kļūdas atbilde - RFC 9457 Problem Details
HTTP/1.1 429 Too Many Requests Content-Type: application/problem+json Retry-After: 30 { "type": "https://api.piemers.lv/kludas/rate-limit", "title": "Pārāk daudz pieprasījumu", "status": 429, "detail": "Limits 100 pieprasījumi minūtē ir pārsniegts.", "instance": "/v1/lietotaji" }
Atsauces
Starptautiskie standarti un specifikācijas
Saistība ar NIS2
Droša API izstrāde un testēšana atbilst NIS2 (ES 2022/2555) 21. panta 2. punkta e) apakšpunkta prasībām par drošību iegādē, izstrādē un uzturēšanā.
GDPR
Atbildē jāatklāj tikai nepieciešamais (datu minimizācija) - pārmērīga datu atklāšana (OWASP API3) ir arī personas datu aizsardzības pārkāpums.
Atruna
Materiāls ir izglītojošs pārskats, nevis standartu pilnais teksts. Konkrētai ieviešanai vienmēr jāskata oficiālais avots.
Saīsinājumi
Ceļvedī lietotie saīsinājumi: oriģinālais nosaukums un ko tas nozīmē.
- API
- Application Programming Interface - vienošanās, kā programmas apmainās ar datiem.
- REST
- Representational State Transfer - API stils, kurā resursus adresē ar URL un darbības izsaka ar HTTP metodēm.
- HTTP
- Hypertext Transfer Protocol - tīmekļa pieprasījumu un atbilžu protokols.
- JSON
- JavaScript Object Notation - teksta formāts datu apmaiņai.
- HATEOAS
- Hypermedia as the Engine of Application State - atbilde satur saites uz nākamajām iespējamajām darbībām.
- GraphQL
- Vaicājumu valoda, kurā klients pats norāda, kurus laukus vajag.
- gRPC / RPC
- Remote Procedure Call - attālināta funkcijas izsaukšana; gRPC - Google ātrais binārais variants.
- SOAP / WSDL
- Simple Object Access Protocol / Web Services Description Language - vecāks XML API protokols un tā līguma apraksts.
- OAuth 2.0
- Standarts, kā lietotne saņem atļauju piekļūt datiem lietotāja vārdā, nezinot viņa paroli.
- OIDC
- OpenID Connect - OAuth 2.0 papildinājums, kas pasaka arī, kas ir lietotājs.
- PKCE
- Proof Key for Code Exchange - aizsardzība, lai pārtverts autorizācijas kods nederētu citam.
- JWT
- JSON Web Token - parakstīts tokens ar datiem par lietotāju un tiesībām.
- mTLS
- mutual TLS - savienojums, kurā sertifikātu uzrāda gan klients, gan serveris.
- BOLA
- Broken Object Level Authorization - lietotājs piekļūst svešam objektam, nomainot identifikatoru (OWASP API1).
- BOPLA
- Broken Object Property Level Authorization - atbilde atklāj vai ļauj mainīt laukus, kas lietotājam nepienākas (API3).
- BFLA
- Broken Function Level Authorization - parasts lietotājs izsauc administratora funkciju (API5).
- SSRF
- Server-Side Request Forgery - uzbrucējs liek serverim izsaukt adresi viņa vietā, arī iekšējā tīklā (API7).
- CORS
- Cross-Origin Resource Sharing - noteikumi, no kurām vietnēm pārlūks drīkst izsaukt API.
- DoS
- Denial of Service - pakalpojuma atteice - sistēmu pārslogo, līdz tā vairs neatbild.
- WAF
- Web Application Firewall - ugunsmūris, kas filtrē uzbrukumus tīmekļa lietotnēm.
- CDN
- Content Delivery Network - serveru tīkls, kas piegādā saturu no lietotājam tuvākās vietas.
- LB / ALB / NLB
- Load Balancer / Application / Network Load Balancer - slodzes balansētājs; ALB strādā ar HTTP, NLB ar TCP.
- TLS
- Transport Layer Security - šifrēts savienojums tīklā.
- ETag
- Entity Tag - atbildes versijas apzīmējums - ļauj kešot un nesūtīt nemainītu saturu.
- OpenAPI / OAS
- OpenAPI Specification - mašīnlasāms API apraksts, no kura ģenerē dokumentāciju un klientus.
- RFC
- Request for Comments - interneta standartu dokumentu sērija (piem., RFC 9110 - HTTP).
- OWASP
- Open Worldwide Application Security Project - bezpeļņas kopiena, kas publicē lietotņu drošības vadlīnijas un Top 10.
- SPA
- Single-Page Application - tīmekļa lietotne, kas darbojas vienā lapā un datus ņem no API.