Baratanje HTTP kolačićima u jeziku PHP - GASERI


HTTP kolačić (engl. HTTP cookie, Wikipedia, više detalja o kolačićima na MDN-u) je maleni dio podataka koji korisnički agent pohranjuje na računalu korisnika kod pregledavanja web sjedišta. Na temelju pohranjenih podataka web sjedište pamti...



Onion Details



Page Clicks: 0

First Seen: 03/15/2024

Last Indexed: 10/23/2024

Domain Index Total: 397



Onion Content



Preskoči na sadržaj Baratanje HTTP kolačićima u jeziku PHP HTTP kolačić (engl. HTTP cookie , Wikipedia , više detalja o kolačićima na MDN-u ) je maleni dio podataka koji korisnički agent pohranjuje na računalu korisnika kod pregledavanja web sjedišta. Na temelju pohranjenih podataka web sjedište pamti stanje koje je korisnik stvorio svojim pregledavanjem, npr. predmete dodane u košaricu za kupnju, prijavu na zatvoreni dio sjedišta upotrebom određenog korisničkog računa ili tekst prethodnih pretraga arhive audiovizualnih datoteka. Način rada kolačića HTTP zaglavlje Set-Cookie je dio odgovora na zahtjev i koristi se za postavljanje kolačića koji se pohranjuju na klijentskoj strani ( više detalja o HTTP zaglavlju Set-Cookie na MDN-u ). Sadržaj zaglavlja Set-Cookie je oblika cookie-name=cookie-value , pri čemu je cookie-name ime kolačića, a cookie-value njegova vrijednost. Primjerice, kako bi poslužitelj pohranio na klijentu identifikator korisnika, odnosno kolačić imena id koji ima vrijednost 1234 , zaglavlje Set-Cookie bit će oblika: Set-Cookie: id=1234 Način pohrane kolačića je prepušten implementaciji pa cURL pohranjuje u tekstualnu datoteku , a Firefox u relacijsku bazu podataka . Kod slanja idućeg zahtjeva korisnički agent učitava pohranjene kolačiće i šalje ih u HTTP zaglavlju Cookie ( više detalja o HTTP zaglavlju Cookie na MDN-u ). U konkretnom primjeru s identifikatorom korisnika zaglavlje Cookie bit će oblika: Cookie: id=1234 Postavljanje kolačića Interpreter PHP-a podržava postavljanje kolačića funkcijom setcookie() ( dokumentacija ). Postavimo kolačić imena kolacic i vrijednosti Bugnes lyonnaises na način: GET / HTTP/1.1 > Host: localhost:8000 > User-Agent: curl/7.72.0 > Accept: */* > * Mark bundle as not supporting multiuse 1759233600 , "path" => "/slasticarna" ]); postavit ćemo da kolačić ističe u trenutku 1759233600 Unix vremena, odnosno 30. rujna 2025. u 12 sati po UTC-u i odnosi se na putanju /slasticarna . Osim ova dva, u asocijativnom polju s opcijama dostupni su nam i ključevi: "domain" , kojim postavljamo domenu "secure" , kojim postavljamo da se kolačić šalje samo kad se koristi HTTPS "httponly" , kojim postavljamo da je kolačić dostupan samo preko HTTP-a "samesite" , kojim postavljamo ograničenje kolačića na domenu (vrijednost "Lax" postavlja labavo ograničenje, a vrijednost "Strict" postavlja strogo ograničenje) Primanje kolačića Polje $_COOKIE ( dokumentacija ) sadrži sve kolačiće primljene od strane klijenta. U tom polju ključevi su nazivi kolačića, a vrijednosti upravo njihove vrijednosti. Za ilustraciju, provjerimo funkcijom array_key_exists() ( dokumentacija ) postoji li u tom polju kolačić pod nazivom kolacic , a zatim, ako postoji, dohvatimo njegovu vrijednost i ispišimo je: GET / HTTP/1.1 > Host: localhost:8000 > User-Agent: curl/7.72.0 > Accept: */* > Cookie: kolacic = Bugnes%20lyonnaises > * Mark bundle as not supporting multiuse Ranije ste naručili " . $prethodni_kolac . ". \n " ; } else { http_response_code ( 404 ); echo " Dosad niste naručili nijedan kolač. \n " ; } else if ( $_SERVER [ "REQUEST_METHOD" ] == "POST" ) { // narudžba kolača slučajnim odabirom } $j = json_encode ( $orders ); file_put_contents ( $datoteka , $j ); Uvjerimo se da dosad nismo naručili nijedan kolač: curl -v http://localhost:8000/kolaci * Trying ::1:8000... * Connected to localhost (::1) port 8000 (#0) > GET /kolaci HTTP/1.1 > Host: localhost:8000 > User-Agent: curl/7.74.0 > Accept: */* > * Mark bundle as not supporting multiuse Dosad niste naručili nijedan kolač. * Closing connection 0 Uočimo kako je stvorena i datoteka public/orders.json sadržaja: [] Prazno polje indicira da dosad još nije bilo narudžbi. Osvježavanje podataka o korisnikoj narudžbi Kod naručivanja, odabir kolača ćemo izvesti slučajno među ponuđenima funkcijom array_rand() ( dokumentacija ) koja će slučajno odabrati ključ iz danog polja. Putem ključa dohvatit ćemo kolač. Ako je korisnik poslao kolačić u kojemu je sadržan podatak user_id i taj identifikator postoji u polju $orders , zamijenit ćemo zapis o prethodno naručenom kolaču novim (to činimo ovdje radi jednostavnosti; u praksi web aplikacije uglavnom dopunjavaju podatke, a vrlo rijetko brišu išta). Slično kao kod dohvaćanja podataka, ako korisnik nije poslao kolačić, ili je poslao kolačić koji nema podatak user_id , ili je poslao kolačić čiji user_id ne postoji u polju, poslužitelj će u polju $orders stvoriti podatke pod novim indeksom pa taj indeks poslati korisniku u kolačiću pod user_id . Ranije ste naručili " . $prethodni_kolac . ". \n " ; } else { http_response_code ( 404 ); echo " Dosad niste naručili nijedan kolač. \n " ; } else if ( $_SERVER [ "REQUEST_METHOD" ] == "POST" ) { $kolac_key = array_rand ( $kolaci ); $kolac = $kolaci [ $kolac_key ]; echo " Naručili ste " . $kolac . ". \n " ; if ( array_key_exists ( "user_id" , $_COOKIE ) && array_key_exists ( $_COOKIE [ "user_id" ], $orders )) { $user_id = $_COOKIE [ "user_id" ]; $orders [ $user_id ] = $kolac ; } else { $orders [] = $kolac ; $user_id = array_key_last ( $orders ); setcookie ( "user_id" , $user_id ); } $j = json_encode ( $orders ); file_put_contents ( $datoteka , $j ); Isprobajmo navedeni kod: $ curl -v -c cookies.txt -X POST http://localhost:8000/kolaci * Trying ::1:8000... * Connected to localhost ( ::1 ) port 8000 ( #0) > POST /kolaci HTTP/1.1 > Host: localhost:8000 > User-Agent: curl/7.74.0 > Accept: */* > * Mark bundle as not supporting multiuse Naručili ste Babka. * Closing connection 0 Stvorena je datoteka cookies.txt sadržaja: # Netscape HTTP Cookie File # https://curl.se/docs/http-cookies.html # This file was generated by libcurl! Edit at your own risk. localhost FALSE / FALSE 0 user_id 0 Iskoristimo tu datoteku kod slanja idućeg zahtjeva: $ curl -v -b cookies.txt http://localhost:8000/kolaci * Trying ::1:8000... * Connected to localhost ( ::1 ) port 8000 ( #0) > GET /kolaci HTTP/1.1 > Host: localhost:8000 > User-Agent: curl/7.74.0 > Accept: */* > Cookie: user_id = 0 > * Mark bundle as not supporting multiuse Ranije ste naručili Babka. * Closing connection 0 Možemo se uvjeriti da je stvorena datoteka orders.json koja sadrži listu: [ "Babka" ] Warning Iz sigurnosne perspektive, korištenje kratkih, predvidljivih i nepromjenjivih identifikatora korisnika u kolačićima kao što su redom brojevi 0, 1, 2, ... je loš pristup jer otvara puno prostora za napad. U praksi bi postavljanje kolačića bilo nešto složenije, ali ovakav pristup je procesu učenja sasvim dovoljan za ilustraciju načina postavljanja i dohvaćanja kolačića. Isprobajmo naručivanje kolača kao korisnik koji je već ranije naručio kolač: $ curl -v -b cookies.txt -X POST http://localhost:8000/kolaci * Trying ::1:8000... * Connected to localhost ( ::1 ) port 8000 ( #0) > POST /kolaci HTTP/1.1 > Host: localhost:8000 > User-Agent: curl/7.74.0 > Accept: */* > Cookie: user_id = 0 > * Mark bundle as not supporting multiuse Naručili ste Kremówka. * Closing connection 0 Uvjerimo se da je ova narudžba u datoteci orders.json zamijenila prethodnu: [ "Krem\u00f3wka" ] Naručimo još jedan kolač kao novi korisnik: $ curl -v -c cookies-new.txt -X POST http://localhost:8000/kolaci * Trying ::1:8000... * Connected to localhost ( ::1 ) port 8000 ( #0) > POST /kolaci HTTP/1.1 > Host: localhost:8000 > User-Agent: curl/7.74.0 > Accept: */* > * Mark bundle as not supporting multiuse Naručili ste Kladdkaka. * Closing connection 0 Uočimo kako je u zaglavlju Set-Cookie u odgovoru postavljen identifikator novog korisnika na 1. Datoteka orders.json sad ima sadržaj: [ "Krem\u00f3wka" , "Kladdkaka" ] Author: Vedran Miletić