Sessions

Το HTTP είναι ένα πρωτόκολλο χωρίς κατάσταση, αλλά σχεδόν κάθε εφαρμογή χρειάζεται να διατηρεί την κατάσταση μεταξύ των αιτημάτων, για παράδειγμα, το περιεχόμενο ενός καλαθιού αγορών. Αυτός είναι ακριβώς ο σκοπός των sessions. Θα δείξουμε:

  • πώς να χρησιμοποιείτε τα sessions
  • πώς να αποφύγετε τις συγκρούσεις ονομάτων
  • πώς να ορίσετε τη λήξη

Όταν χρησιμοποιείτε sessions, κάθε χρήστης λαμβάνει ένα μοναδικό αναγνωριστικό που ονομάζεται session ID, το οποίο μεταδίδεται σε ένα cookie. Αυτό χρησιμεύει ως κλειδί για τα δεδομένα του session. Σε αντίθεση με τα cookies, τα οποία αποθηκεύονται στην πλευρά του προγράμματος περιήγησης, τα δεδομένα του session αποθηκεύονται στην πλευρά του διακομιστή.

Ρυθμίζουμε το session στην διαμόρφωση, η επιλογή του χρόνου λήξης είναι ιδιαίτερα σημαντική.

Η διαχείριση του session γίνεται από το αντικείμενο Nette\Http\Session, στο οποίο μπορείτε να αποκτήσετε πρόσβαση ζητώντας το μέσω έγχυσης εξάρτησης. Στους presenters, απλά καλέστε $session = $this->getSession().

Εγκατάσταση και απαιτήσεις

Έναρξη Session

Από προεπιλογή, το Nette ξεκινά αυτόματα το session τη στιγμή που αρχίζουμε να διαβάζουμε ή να γράφουμε δεδομένα σε αυτό. Μπορείτε να ξεκινήσετε το session χειροκίνητα χρησιμοποιώντας το $session->start().

Όταν ξεκινά ένα session, η PHP στέλνει κεφαλίδες HTTP που επηρεάζουν την προσωρινή αποθήκευση, δείτε session_cache_limiter, και ενδεχομένως ένα cookie με το session ID. Επομένως, είναι απαραίτητο να ξεκινάτε πάντα το session πριν στείλετε οποιαδήποτε έξοδο στο πρόγραμμα περιήγησης, διαφορετικά θα προκληθεί εξαίρεση. Εάν γνωρίζετε ότι το session θα χρησιμοποιηθεί κατά την απόδοση της σελίδας, ξεκινήστε το χειροκίνητα εκ των προτέρων, για παράδειγμα, στον presenter.

Στη λειτουργία ανάπτυξης, το Tracy ξεκινά το session επειδή το χρησιμοποιεί για την εμφάνιση των γραμμών με ανακατευθύνσεις και αιτήματα AJAX στο Tracy Bar.

Ενότητες

Στην καθαρή PHP, ο χώρος αποθήκευσης δεδομένων του session υλοποιείται ως ένας πίνακας προσβάσιμος μέσω της καθολικής μεταβλητής $_SESSION. Το πρόβλημα είναι ότι οι εφαρμογές συνήθως αποτελούνται από έναν αριθμό ανεξάρτητων τμημάτων, και εάν όλα έχουν πρόσβαση μόνο σε έναν πίνακα, αργά ή γρήγορα θα προκύψει σύγκρουση ονομάτων.

Το Nette Framework λύνει αυτό το πρόβλημα διαιρώντας ολόκληρο τον χώρο σε ενότητες (αντικείμενα Nette\Http\SessionSection). Κάθε μονάδα χρησιμοποιεί τότε τη δική της ενότητα με ένα μοναδικό όνομα, και δεν μπορεί να προκύψει σύγκρουση.

Λαμβάνουμε μια ενότητα από το session:

$section = $session->getSection('μοναδικό όνομα');

Στον presenter, απλά χρησιμοποιήστε το getSession() με μια παράμετρο:

// $this είναι ένας Presenter
$section = $this->getSession('μοναδικό όνομα');

Η ύπαρξη μιας ενότητας μπορεί να ελεγχθεί με τη μέθοδο $session->hasSection('μοναδικό όνομα').

Η εργασία με την ίδια την ενότητα είναι τότε πολύ εύκολη χρησιμοποιώντας τις μεθόδους set(), get() και remove():

// εγγραφή μεταβλητής
$section->set('userName', 'franta');

// ανάγνωση μεταβλητής, επιστρέφει null εάν δεν υπάρχει
echo $section->get('userName');

// διαγραφή μεταβλητής
$section->remove('userName');

Για να λάβετε όλες τις μεταβλητές από την ενότητα, μπορείτε να χρησιμοποιήσετε έναν βρόχο foreach:

foreach ($section as $key => $val) {
	echo "$key = $val";
}

Ρύθμιση Λήξης

Είναι δυνατό να οριστεί η λήξη για μεμονωμένες ενότητες ή ακόμη και για μεμονωμένες μεταβλητές. Μπορούμε να αφήσουμε τη σύνδεση του χρήστη να λήξει σε 20 λεπτά, αλλά ταυτόχρονα να θυμόμαστε το περιεχόμενο του καλαθιού αγορών.

// η ενότητα λήγει μετά από 20 λεπτά
$section->setExpiration('20 minutes');

Για να ορίσετε τη λήξη μεμονωμένων μεταβλητών, χρησιμοποιήστε την τρίτη παράμετρο της μεθόδου set():

// η μεταβλητή 'flash' λήγει μετά από 30 δευτερόλεπτα
$section->set('flash', $message, '30 seconds');

Μην ξεχνάτε ότι ο χρόνος λήξης ολόκληρου του session (δείτε διαμόρφωση session) πρέπει να είναι ίσος ή μεγαλύτερος από τον χρόνο που ορίζεται για μεμονωμένες ενότητες ή μεταβλητές.

Η ακύρωση μιας προηγουμένως ορισμένης λήξης επιτυγχάνεται με τη μέθοδο removeExpiration(). Η άμεση ακύρωση ολόκληρης της ενότητας διασφαλίζεται από τη μέθοδο remove().

Συμβάντα $onStart, $onBeforeWrite

Το αντικείμενο Nette\Http\Session έχει συμβάντα $onStart και $onBeforeWrite, οπότε μπορείτε να προσθέσετε επανακλήσεις που καλούνται μετά την έναρξη του session ή πριν από την εγγραφή του στον δίσκο και τον επακόλουθο τερματισμό του.

$session->onBeforeWrite[] = function () {
	// γράφουμε δεδομένα στο session
	$this->section->set('basket', $this->basket);
};

Διαχείριση Session

Επισκόπηση των μεθόδων της κλάσης Nette\Http\Session για τη διαχείριση του session:

start(): void

Ξεκινά το session.

isStarted(): bool

Έχει ξεκινήσει το session;

close(): void

Τερματίζει το session. Το session τερματίζεται αυτόματα στο τέλος της εκτέλεσης του σεναρίου.

destroy(): void

Τερματίζει και διαγράφει το session.

exists(): bool

Περιέχει το αίτημα HTTP ένα cookie με το session ID;

regenerateId(): void

Δημιουργεί ένα νέο τυχαίο session ID. Τα δεδομένα διατηρούνται.

getId(): string

Επιστρέφει το session ID.

Διαμόρφωση

Ρυθμίζουμε το session στην διαμόρφωση. Εάν γράφετε μια εφαρμογή που δεν χρησιμοποιεί DI container, αυτές οι μέθοδοι χρησιμοποιούνται για τη διαμόρφωση. Πρέπει να κληθούν πριν από την έναρξη του session.

setName (string $name): static

Ορίζει το όνομα του cookie στο οποίο μεταδίδεται το session ID. Το προεπιλεγμένο όνομα είναι PHPSESSID. Είναι χρήσιμο εάν εκτελείτε πολλές διαφορετικές εφαρμογές στον ίδιο ιστότοπο.

getName(): string

Επιστρέφει το όνομα του cookie στο οποίο μεταδίδεται το session ID.

setOptions (array $options)static

Διαμορφώνει το session. Μπορείτε να ορίσετε όλες τις PHP οδηγίες session (σε μορφή camelCase, π.χ. αντί για session.save_path γράφουμε savePath) καθώς και το readAndClose.

setExpiration (?string $time)static

Ορίζει τον χρόνο αδράνειας μετά τον οποίο λήγει το session.

setCookieParameters (string $path, ?string $domain=null, ?bool $secure=null, ?string $samesite=null)static

Ρύθμιση παραμέτρων για το cookie. Μπορείτε να αλλάξετε τις προεπιλεγμένες τιμές των παραμέτρων στην διαμόρφωση.

setSavePath (string $path)static

Ορίζει τον κατάλογο όπου αποθηκεύονται τα αρχεία session.

setHandler (\SessionHandlerInterface $handler)static

Ορίζει έναν προσαρμοσμένο χειριστή, δείτε την τεκμηρίωση της PHP.

Ασφάλεια Πρώτα

Ο διακομιστής υποθέτει ότι επικοινωνεί πάντα με τον ίδιο χρήστη, εφόσον τα αιτήματα συνοδεύονται από το ίδιο session ID. Ο ρόλος των μηχανισμών ασφαλείας είναι να διασφαλίσουν ότι αυτό συμβαίνει πραγματικά και ότι δεν είναι δυνατό να κλαπεί ή να πλαστογραφηθεί το αναγνωριστικό.

Επομένως, το Nette Framework διαμορφώνει σωστά τις οδηγίες PHP έτσι ώστε το session ID να μεταδίδεται μόνο σε cookies, να το καθιστά μη προσβάσιμο από JavaScript και να αγνοεί τυχόν αναγνωριστικά στο URL. Επιπλέον, σε κρίσιμες στιγμές, όπως η σύνδεση του χρήστη, δημιουργεί ένα νέο session ID.

Η συνάρτηση ini_set χρησιμοποιείται για τη διαμόρφωση της PHP, την οποία δυστυχώς ορισμένοι πάροχοι φιλοξενίας απαγορεύουν. Εάν αυτό συμβαίνει και με τον δικό σας πάροχο, προσπαθήστε να διαπραγματευτείτε μαζί του για να σας επιτρέψει τη συνάρτηση ή τουλάχιστον να διαμορφώσει τον διακομιστή.

έκδοση: 4.0