PHP:$_SESSION - Quali sono i pro e i contro della memorizzazione dei dati utilizzati temporaneamente nella variabile $_SESSION

StackOverflow https://stackoverflow.com/questions/77826

  •  09-06-2019
  •  | 
  •  

Domanda

Una cosa che ho iniziato a fare più spesso di recente è recuperare alcuni dati all'inizio di un compito e memorizzandolo in $_SESSION['myDataForTheTask'].

Ora sembra molto conveniente farlo, ma non so nulla di prestazioni, rischi per la sicurezza o simili, utilizzando questo approccio.È qualcosa che viene fatto regolarmente da programmatori con maggiore esperienza o è più una cosa amatoriale?

Per esempio:

if (!isset($_SESSION['dataentry']))
{
    $query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=" . mysql_real_escape_string($_GET['wave_id']);
    $result_taskinfo = $db->query($query_taskinfo);
    $row_taskinfo = $result_taskinfo->fetch_row();

        $dataentry = array("pcode" => $row_taskinfo[0], "modules" => $row_taskinfo[1], "data_id" => 0, "wavenum" => $row_taskinfo[2], "prequest" => FALSE, "highlight" => array());

        $_SESSION['dataentry'] = $dataentry;
}
È stato utile?

Soluzione

Bene, le variabili di sessione sono in realtà uno degli unici modi (e probabilmente il più efficiente) per avere queste variabili disponibili per tutto il tempo in cui il visitatore rimane sul sito web, non esiste un modo reale per un utente di modificarle (a parte un exploit nel tuo codice o nell'interprete PHP) quindi sono abbastanza sicuri.

È un buon modo per memorizzare le impostazioni che possono essere modificate dall'utente, poiché puoi leggere le impostazioni dal database una volta all'inizio di una sessione ed è disponibile per l'intera sessione, devi solo effettuare ulteriori chiamate al database se le impostazioni vengono modificati e ovviamente, come mostri nel codice, è banale scoprire se le impostazioni esistono già o se devono essere estratte dal database.

Non riesco a pensare a nessun altro modo per archiviare le variabili temporanee in modo sicuro (poiché i cookie possono essere facilmente modificati e questo non sarà desiderabile nella maggior parte dei casi), quindi $_SESSION sarebbe la strada da percorrere

Altri suggerimenti

Il meccanismo $_SESSION utilizza i cookie.

Nel caso di Firefox (e forse del nuovo IE, non ho controllato personalmente) ciò significa che la sessione è condivisa tra le schede aperte.Non è qualcosa che ti aspetti per impostazione predefinita.E significa che la sessione non è più "qualcosa di specifico per una singola finestra/utente".

Ad esempio, se hai aperto due schede per accedere al tuo sito e poi sei loggato come root utilizzando la prima scheda, otterrai i privilegi di root nell'altra.

Ciò è davvero scomodo, soprattutto se si codifica un client di posta elettronica o qualcos'altro (come l'e-shop).In questo caso dovrai gestire le sessioni manualmente o introdurre chiavi costantemente rigenerate nell'URL o fare qualcos'altro.

Utilizzo sempre la variabile di sessione per memorizzare informazioni per gli utenti.Non ho riscontrato alcun problema con le prestazioni.I dati della sessione vengono estratti in base al cookie (o PHPSESSID se hai disattivato i cookie).Non lo vedo più un rischio per la sicurezza rispetto a qualsiasi altra autenticazione basata su cookie e probabilmente più sicuro rispetto alla memorizzazione dei dati effettivi nel cookie dell'utente.

Solo per farti sapere, hai un problema di sicurezza con la tua istruzione SQL:

SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=".$_GET['wave_id'];

Dovresti MAI, RIPETO MAI, prendi i dati forniti dall'utente e usali per eseguire un'istruzione SQL senza prima disinfettarli.Lo racchiuderei tra virgolette e aggiungerei la funzione mysql_real_escape_string().Questo ti proteggerà dalla maggior parte degli attacchi.Quindi la tua linea sarebbe simile a:

$query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id='".mysql_real_escape_string($_GET['wave_id'])."'";

Ci sono alcuni fattori da considerare quando si decide dove archiviare i dati temporanei.L'archiviazione delle sessioni è ottima per i dati specifici di un singolo utente.Se ritieni che il gestore di archiviazione della sessione basato su file predefinito sia inefficiente, puoi implementare qualcos'altro, possibilmente utilizzando un database o un tipo di backend memcache.Vedere session_set_save_handler per maggiori informazioni.

Trovo che sia una cattiva pratica archiviare dati comuni nella sessione di un utente.Esistono posti migliori per archiviare i dati a cui accederanno frequentemente più utenti e archiviando questi dati nella sessione duplicherai i dati per ciascun utente che necessita di questi dati.Nel tuo esempio, potresti impostare un diverso tipo di motore di archiviazione per questi dati wave (basato su wave_id) che NON è legato specificamente alla sessione di un utente.In questo modo estrarrai i dati una volta e li memorizzerai in un posto in cui diversi utenti possano accedere ai dati senza richiedere un altro pull.

Se stai utilizzando il tuo server o in un ambiente in cui nessuno può curiosare sui tuoi file/memoria sul server, i dati della sessione sono sicuri.Sono memorizzati sul server e al client viene inviato solo un cookie di identificazione.Il problema è, ovviamente, se altre persone riescono a rubare il biscotto e impersonare qualcun altro.Utilizzare HTTPS e assicurarsi di non inserire l'ID di sessione negli URL dovrebbe proteggere i tuoi utenti dalla maggior parte di questi problemi.(XSS potrebbe ancora essere utilizzato per rubare i cookie se non stai attento, vedi Post di Jeef Atwood su questo pure.)

Per quanto riguarda cosa memorizzare in una variabile di sessione, inserisci lì i tuoi dati se vuoi farvi riferimento nuovamente su un'altra pagina, come un carrello della spesa, ma non inserirli se sono solo dati temporanei utilizzati per produrre il risultato di questo pagina, come un elenco di tag per il post attualmente visualizzato.Le sessioni riguardano dati persistenti per utente.

Un altro modo per migliorare la convalida dell'input è eseguire il cast della variabile _GET['wave_id']:

$query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=".(int)$_GET['wave_id']." LIMIT 1";

Presumo che wave_id sia un numero intero e che esista una sola risposta.

Volere

Alcuni altri svantaggi dell'utilizzo delle sessioni:

  1. $_SESSION i dati scadranno dopo sessione.gc_maxlifetime secondi di inattività.
  2. Dovrai ricordarti di chiamare session_start() per ogni script che utilizzerà i dati della sessione.
  3. Scalare il sito web bilanciando il carico su più server potrebbe essere un problema perché l'utente dovrà essere indirizzato ogni volta allo stesso server.Risolvi questo problema con "Sessioni adesive".

Gli elementi $_SESSION vengono archiviati nella sessione, che, per impostazione predefinita, viene conservata su disco.Non è necessario creare il proprio array e inserirlo in una voce dell'array "dataentry" come hai fatto tu.Puoi semplicemente usare $_SESSION['pcode'], $_SESSION['modules'] e così via.

Come ho detto, la sessione viene archiviata su disco e un puntatore alla sessione viene archiviato in un cookie.L'utente quindi non può ottenere facilmente i dati della sessione.

IMO, è perfettamente accettabile archiviare cose nella sessione.È un ottimo modo per rendere i dati persistenti.In molti casi è anche più sicuro che archiviare tutto nei cookie.Ecco alcune preoccupazioni:

  • È possibile che qualcuno prenda il controllo di una sessione, quindi se intendi utilizzarlo per tenere traccia dell'autorizzazione dell'utente, fai attenzione.Leggere Questo per maggiori informazioni.
  • Può essere un modo molto pigro per conservare i dati.Non buttare tutto nella sessione in modo da non doverlo interrogare in seguito.
  • Se intendi archiviare oggetti nella sessione, i relativi file di classe dovranno essere inclusi prima che la sessione venga avviata alla richiesta successiva oppure dovrai aver configurato un caricatore automatico.

Zend Framework dispone di un'utile libreria per la gestione dei dati di sessione che aiuta con la scadenza e la sicurezza (per cose come i captcha).Hanno anche un'utile spiegazione delle sessioni.Vedere http://framework.zend.com/manual/en/zend.session.html

Ho trovato le sessioni molto utili, ma alcune cose da notare:

1) Che PHP possa memorizzare le tue sessioni in una cartella tmp o in un'altra directory che potrebbe essere accessibile ad altri utenti sul tuo server.È possibile modificare la directory in cui vengono archiviate le sessioni accedendo al file php.ini.

2) Se stai configurando un sistema di alto valore che necessita di una sicurezza molto rigorosa, potresti voler crittografare i dati prima di inviarli alla sessione e decrittografarli per utilizzarli.Nota:questo potrebbe creare un sovraccarico eccessivo a seconda della capacità del traffico/server.

3) Ho trovato che session_destroy();non elimina subito la sessione, devi comunque attendere che il garbage collector PHP ripulisca le sessioni.È possibile modificare la frequenza con cui viene eseguito il Garbage Collector nel file php.ini.Ma non sembra ancora molto affidabile, maggiori informazioni http://www.captain.at/howto-php-sessions.php

Potresti considerare quanto sia REST-ful?

cioè.vedere il paragrafo "Comunicare apolide" in "Una breve introduzione al REST"...

"Il riposo impone che lo stato sia trasformato in stato di risorse o mantenuta sul cliente.In altre parole, un server non dovrebbe conservare una sorta di stato di comunicazione per nessuno dei clienti con cui comunica oltre un'unica richiesta. "

(o uno qualsiasi degli altri collegamenti su Wikipedia per RIPOSO)

Quindi, nel tuo caso, 'wave_id' è una risorsa sensata da GET, ma vuoi davvero memorizzarlo nella SESSION?Certamente memcached è la tua soluzione per memorizzare nella cache l'oggetto Resource?

Io uso questo approccio un bel po', non vedo alcun problema con esso.A differenza dei cookie, i dati non vengono archiviati lato client, il che spesso è un grosso errore.

Come ogni cosa, però, fai solo attenzione a disinfettare sempre l'input dell'utente, soprattutto se inserisci l'input dell'utente nella variabile $_SESSION, quindi in seguito utilizzi quella variabile in una query SQL.

Questa è una cosa abbastanza comune da fare e la sessione sarà generalmente più veloce dei continui accessi al database.Sono anche ragionevolmente sicuri, poiché gli sviluppatori PHP hanno lavorato duramente per prevenire il dirottamento della sessione.

L'unico problema è che devi ricordarti di ricostruire la voce della sessione quando qualcosa cambia.Inoltre, se un utente diverso da quello proprietario della sessione modifica qualcosa che comporta la necessità di aggiornare questa chiave, non esiste un modo semplice per notificare al sistema di aggiornare questa chiave di sessione.Forse non è un grosso problema, ma qualcosa di cui dovresti essere consapevole.

$_SESSION è molto utile in termini di sicurezza, poiché è un modo lato server per memorizzare informazioni mentre un utente è attivamente sulle tue pagine, quindi difficile da hackerare a meno che il tuo vero file php o server non abbia punti deboli che vengono sfruttati.Un'ottima implementazione è la memorizzazione di una variabile per confermare che l'utente ha effettuato l'accesso e consentire l'esecuzione di azioni solo se l'accesso è confermato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top