Le sessioni PHP durano veramente fino alla chiusura del browser e la rigenerazione della sessione sulle richieste di pagina

1

Abbiamo un problema in cui le sessioni terminano dopo poco tempo, 1440 secondi in base alle impostazioni di gc_maxlifetime che sembrano coerenti con il problema. Il PHPSESSID dice che scadrà quando termina la sessione - immagino che il browser si chiuda? Suppongo che prima di allora il GC stia pulendo le sessioni scadute, quindi il PHPSESSID, che sopravvive alla sessione sul server, non corrisponde a nessuna sessione. È giusto? Immagino che venga rilasciato un nuovo cookie PHPSESSID quando la sessione viene ricreata?

L'estensione di sessiongc.maxlifetime è un'opzione, dobbiamo considerare come il sito live gestirà i dati di sessione aggiuntivi sul server. Spostare le sessioni su Redis è un'opzione anche qui.

In alternativa, in aggiunta, è possibile rigenerare la sessione senza perdere i dati della sessione? Ad esempio, ogni volta che l'utente apre una pagina, assumiamo che siano ancora attivi, quindi rigenera la sessione estendendo così la sua durata di vita ai 1440 secondi (o qualsiasi altra cosa estendiamo a). Quindi, anche se abbiamo una sessione di breve durata, la sessione viene distrutta solo quando l'utente rimane inattivo (non fa più caricamenti di pagina) per quel periodo di tempo - quindi se continuo a fare clic ogni 10 minuti, anche io non sarò mai disconnesso .

Vorrei anche notare che abbiamo milioni di visualizzazioni di pagina e qualche migliaio di utenti autenticati in un dato momento. Quindi, la semplice estensione di gc_maxlifetime è qualcosa che dobbiamo seguire con attenzione, credo.

    
posta Martyn 18.02.2016 - 04:13
fonte

1 risposta

3

Eseguiamo una chiamata AJAX sul nostro sito che invia un heartbeat al server una volta ogni due minuti, mantenendo la sessione attiva finché la pagina è aperta sul browser. Una volta chiusa la pagina , la sessione scade da sola.

Ecco uno snippet del codice che ho scritto per realizzare questo. Si prega di scusare tutta la terminologia cardiaca:)

/**
 * Heartbeat singleton
 */
var Heart = {
    url:         'https://my.domain.tld/EKG', // server script to hit
    logging:     false, // log to console for debugging
    pulse:       300, // heartbeat interval in seconds
    maxTimeouts: 3, // max timeouts before "heart attack" (stop)
    sessionName: 'PHPSESSID', // session cookie name

    // leave these alone
    timeouts:    0,
    timer:       null,
    sessionId:   null,

    /**
     * Begin heartbeats
     */
    start: function() {
        Heart.getSessionId();
        Heart.timer = setInterval(Heart.beat, Heart.pulse * 1000);
    },

    /**
     * Stop heartbeats
     */
    stop: function() {
        clearInterval(Heart.timer);
    },

    /**
     * Send single heartbeat
     */
    beat: function() {
        $.ajax({
            url:     Heart.url,
            headers: {
                'X-Heartbeat-Session': Heart.sessionId
            },
            success:  Heart.thump,
            timeout:  Heart.arrhythmia,
            error:    Heart.infarction
        });
    },

    /**
     * Successful heartbeat handler
     */
    thump: function() {
        Heart.log('thump thump');
        if (Heart.timeouts > 0)
            Heart.timeouts = 0;
    },

    /**
     * Heartbeat timeout handler
     */
    arrhythmia: function() {
        if (++Heart.timeouts >= Heart.maxTimeouts)
            Heart.infarction();
        else
            Heart.log('skipped beat')
                 .beat();
    },

    /**
     * Heartbeat failure handler
     */
    infarction: function() {
        Heart.log('CODE BLUE!! GET THE CRASH CART!!')
             .stop();
    },

    /**
     * Log to console if Heart.logging == true
     */
    log: function(msg) {
        if (Heart.logging)
            console.log(msg);

        return Heart;
    },

    /**
     * Parse cookie string and retrieve PHP session ID
     */
    getSessionId: function() {
        var name    = Heart.sessionName + '=',
            cookies = document.cookie.split(';');

        for (var i = 0; i < cookies.length; i++) {
            var cookie = cookies[i];

            while (cookie.charAt(0) == ' ')
                cookie = cookie.substr(1);

            if (cookie.indexOf(name) == 0) {
                Heart.sessionId = cookie.substr(name.length, cookie.length);
                break;
            }
        }
    }
};

// Start the heart!
Heart.start();

NOTE: This script requires jQuery >= 1.5 Also, if the script you're calling is on a different domain (even a different subdomain) then you need to either change the AJAX call to JSONP or add an Access-Control-Allow-Origin: * header to the response. See HTTP access control (CORS) for more info.

    
risposta data 18.02.2016 - 07:31
fonte

Leggi altre domande sui tag