Izgradnja · Napredno
Predmemoriranje cijena po kupcu: kad brza stranica pokazuje pogrešnu cijenu
Predmemorija stranica sprema jedan odgovor i predaje ga mnogim posjetiteljima. Ako taj odgovor sadrži cijenu po kupcu ili podatke o korisničkom računu, dobit će ih i sljedeći posjetitelj.

Fotografija: Derrick Coetzee, javno dobro (CC0)
U ovom vodiču
Kako predmemorija stranica cijenu jednog kupca posluži drugome
Predmemorija sprema odgovor pod ključem predmemorije i vraća spremljenu kopiju svakom kasnijem zahtjevu koji proizvede isti ključ. Ključ se standardno gradi od metode zahtjeva i URL-a: sheme, hosta, putanje i upitnog niza.
Uzmimo B2B web shop u kojem kupac A ima ugovoreni popust. A je prijavljen i zatraži stranicu proizvoda. Aplikacija pročita kolačić sesije i prikaže stranicu s cijenom kupca A. Predmemorija ispred aplikacije sprema taj odgovor pod ključem za URL proizvoda. Kupac B zatraži isti URL. Ključ je jednak, pa predmemorija vraća spremljenu stranicu, s cijenom kupca A i možda nazivom njegove tvrtke, bez da pita aplikaciju.
Aplikacija je izračunala pravu cijenu, a predmemorija je učinila ono za što je podešena. Greška je u tome što je odgovor ovisio o nečemu što ključ nije sadržavao: tko pita. Svako takvo curenje ima taj oblik. Odgovor varira prema nekoj dimenziji, kao što je kupac, cjenik ili valuta, a ključ je nema.
Dijeljene predmemorije i privatna predmemorija preglednika
- Dijeljena predmemorija sprema odgovore za mnoge korisnike: CDN, obrnuti proxy ispred web poslužitelja ili predmemorija stranica unutar poslužitelja ili aplikacije.
- Privatna predmemorija pripada jednom korisniku. U praksi je to predmemorija preglednika.
Osobni odgovor u dijeljenoj predmemoriji curenje je među kupcima. U predmemoriji preglednika ostaje kod tog korisnika, ali se i dalje može pojaviti nakon odjave, na primjer putem tipke za povratak na računalu koje koristi više ljudi.
HTTP ima jednu ugrađenu zaštitu: odgovor na zahtjev koji je nosio zaglavlje Authorization dijeljena predmemorija ne smije ponovno upotrijebiti, osim ako odgovor to izričito dopušta. Kolačići nemaju takvu zaštitu. Predmemoriji kolačić sesije ne znači ništa. Većina web shopova i portala prijavu čuva u kolačiću, pa zaštita mora doći iz Vaših vlastitih zaglavlja i postavki predmemorije.
Predmemorije stranica ugrađene u aplikacije i poslužiteljske module često slijede vlastita pravila, poput „ne predmemoriraj kad postoji kolačić prijave”. Ako Vaša prijava koristi kolačić koji predmemorija ne poznaje, to se pravilo nikad ne primjenjuje.
HTTP zaglavlja koja odlučuju tko smije spremiti odgovor
Izvorni poslužitelj predmemorijama govori što smiju putem zaglavlja Cache-Control u odgovoru.
- private: odgovor je namijenjen jednom korisniku. Dijeljena predmemorija ne smije ga spremiti, preglednik smije.
- public: svaka predmemorija smije spremiti odgovor, čak i ona koja bi ga inače mogla spremiti samo privatno.
- no-store: nijedna predmemorija, dijeljena ni privatna, ne bi smjela spremiti odgovor.
- no-cache: odgovor se smije spremiti, ali se prije svake ponovne upotrebe mora ponovno provjeriti kod izvora.
- s-maxage: koliko sekundi odgovor vrijedi kao svjež u dijeljenim predmemorijama, gdje nadjačava max-age. Preglednici ga zanemaruju.
Odgovor bez ijednog od tih zaglavlja nije automatski siguran. Predmemorije smiju procijeniti vrijeme svježine kad ga izvor ne zada, a mnogi proxyji i CDN-ovi podešeni su pravilima koja nadjačavaju zaglavlja izvora. Pravilo „predmemoriraj sve”, dodano da ubrza web shop, može učiniti da ispravan Cache-Control: private ne vrijedi ništa.
Pripazite i na Set-Cookie. Ako dijeljena predmemorija spremi odgovor koji postavlja kolačić sesije, kasniji posjetitelji mogu dobiti taj kolačić. Odgovori koji započinju ili mijenjaju sesiju trebaju nositi no-store.
Zašto je Vary: Cookie grub alat
Zaglavlje odgovora Vary imenuje zaglavlja zahtjeva koja postaju dio ključa. Pa Vary: Cookie izgleda kao rješenje: jedna kopija po vrijednosti kolačića.
Rijetko je dobro. Predmemorija uspoređuje cijelo zaglavlje Cookie, koje nosi i kolačiće analitike i privole, različite gotovo za svakog posjetitelja. Anonimni posjetitelji, koji bi svi mogli dijeliti jednu kopiju, dobivaju svaki svoju, i stopa pogodaka se uruši. Osobne stranice i dalje se spremaju u dijeljenu predmemoriju, po jedna kopija po kupcu. A neki CDN-ovi podržavaju Vary samo za određena zaglavlja, pa pročitajte dokumentaciju svojega i testirajte.
Granice sesije: podijelite stranicu, a ne predmemoriju
Pouzdan dizajn razdvaja ono što je svima jednako od onoga što je osobno i svaki dio šalje s vlastitom politikom.
- Prikažite stranicu bez ičega osobnog: podaci o proizvodu, slike, opisi i ili cjenička cijena ili nikakva cijena. Pošaljite je s public i s-maxage kako bi je dijeljena predmemorija mogla posluživati svima.
- Osobne dijelove učitajte zasebnim zahtjevom nakon što stranica stigne: cijena kupca, naziv računa, broj artikala u košarici. Te odgovore pošaljite s private, no-store.
- Za svaki osobni zahtjev provjerite sesiju na poslužitelju.
Ako cijene ovise o cjeniku koji dijeli mnogo kupaca, identifikator cjenika može se dodati u ključ predmemorije, tako da svaka skupina ima svoju kopiju. To je sigurno samo kad identifikator dolazi iz provjerene sesije. Običan kolačić poput price_group=3, koji posjetitelj može urediti, svakome omogućuje da zatraži predmemoriranu stranicu druge skupine.
Valjana je i jednostavnija granica: zaobići dijeljenu predmemoriju za svaki zahtjev s kolačićem sesije. To radi kad su prijavljeni kupci mali udio prometa. Za prometan B2B sustav naručivanja, u kojem je gotovo svaki posjetitelj prijavljen, podijeljeni dizajn važniji je.
Predmemoriranje cijena po kupcu: politika za svaku vrstu stranice
| Vrsta stranice | Osobni sadržaj | Dijeljena predmemorija | Cache-Control u odgovoru |
|---|---|---|---|
| Verzionirani CSS, JavaScript, slike | Nema | Da | public, max-age=31536000, immutable |
| Sadržajne i kataloške stranice bez osobnih cijena | Nema | Da, očisti pri promjeni | public, zadan s-maxage, kratak max-age |
| Okvir stranice proizvoda, cijena se učitava zasebno | Nema u okviru | Da | public, zadan s-maxage, kratak max-age |
| Zahtjev za cijenu kupca ili broj artikala u košarici | Cijena, košarica | Ne | private, no-store |
| Stranica proizvoda prikazana s cijenom kupca | Cijena | Ne | private, no-store |
| Košarica, naplata, račun, narudžbe, računi | Sve | Ne | no-store |
| Prijava, odjava, svaki odgovor koji postavlja kolačić sesije | Sesija | Ne | no-store |
Testirajte s dva kupca i anonimnim posjetiteljem
Ovo curenje ne vidi se kad jedan programer testira s jednim računom. Test treba dva kupca s različitim cijenama i mora proći istim lancem predmemorija kao u produkciji, a ne izravno do aplikacije.
- Odaberite proizvod za koji kupac A i kupac B imaju različite cijene. Očistite predmemoriju za njegov URL ili pričekajte da istekne.
- Zatražite stranicu kao kupac A. Zabilježite prikazanu cijenu, sve podatke o računu i zaglavlja odgovora.
- Zatražite isti URL kao kupac B iz zasebnog profila preglednika ili HTTP klijenta. Zatim ga zatražite bez ikakvih kolačića.
- Usporedite tri odgovora. B mora vidjeti cijenu kupca B, a anonimni posjetitelj ne smije vidjeti nikakvu cijenu kupca, nikakav naziv računa ni tuđi kolačić sesije.
- Pročitajte zaglavlja: Cache-Control, Vary, Set-Cookie i Age. Zaglavlje Age na osobnom odgovoru znači da je došao iz predmemorije. Mnogi CDN-ovi i proxyji dodaju i zaglavlje koje javlja pogodak ili promašaj.
- Ponovite s promijenjenim redoslijedom: prvo anonimno, zatim A, zatim B. Prvi zahtjev puni predmemoriju, pa svaki redoslijed testira drugačiji kvar.
- Isti slijed provedite i na zasebnim zahtjevima za cijenu i košaricu, zatim se odjavite i tipkom za povratak otvorite stranice računa kako biste provjerili predmemoriju preglednika.
Uvrstite taj slijed u automatizirane testove koji se izvode prije svakog izdanja i ponovite ga nakon svake promjene postavki CDN-a, proxyja ili predmemorije. Poboljšanje performansi najvjerojatniji je trenutak u kojem se ta greška unese, a portali za klijente trebaju isti test kao web shopovi.
Pitanja koja često čujemo
Želite da to bude riješeno, a da to ne radite sami?
Recite nam na čemu radite. Čovjek Vam odgovara u roku od jednog radnog dana.
