Ik probeer een constructie te maken in PHP 5.1 waarbij session cookies gebruikt worden met een maximale levensduur van (bv) 10 minuten. Naar mijn idee zou de sessie met onderstaande code na 10 minuten niet meer moeten werken, echter in realiteit werkt de sessie voor 10 minuten, + 1 request.
Uitleg: na 10 minuten kan de gebruiker nog precies één pagina succesvol opvragen, en pas bij de pagina die hij daarna bezoekt wordt hij automatisch uitgelogd. Dit is keer op keer reproduceerbaar.
Dit specifieke probleem kan ik nergens terugvinden op het grote boze interwebz, maar ik vermoedde een probleem met garbage collection. Ik heb de instellingen daarvan nagekeken. De kans dat de garbage collector zijn werk doet is 1/1 (zoals hieronder ook aan de instellingen te zien is).
Ik heb mijn code nu al meerdere keren doorlopen op fouten, maar ik weet niet waar ik verder nog zou moeten zoeken.
Hieronder de relevante snippets in de volgorde waarin ze uitgevoerd worden:
De config die altijd als eerste wordt geladen:
Bij het inloggen zet ik de sessie:
Daarna, bij iedere request voor een beschermde pagina:
loguit.php:
Gezien de gc_divisor en gc_probability beide 1 zijn, is er iets mis met mijn denkwijze?
Uitleg: na 10 minuten kan de gebruiker nog precies één pagina succesvol opvragen, en pas bij de pagina die hij daarna bezoekt wordt hij automatisch uitgelogd. Dit is keer op keer reproduceerbaar.
Dit specifieke probleem kan ik nergens terugvinden op het grote boze interwebz, maar ik vermoedde een probleem met garbage collection. Ik heb de instellingen daarvan nagekeken. De kans dat de garbage collector zijn werk doet is 1/1 (zoals hieronder ook aan de instellingen te zien is).
Ik heb mijn code nu al meerdere keren doorlopen op fouten, maar ik weet niet waar ik verder nog zou moeten zoeken.
Hieronder de relevante snippets in de volgorde waarin ze uitgevoerd worden:
De config die altijd als eerste wordt geladen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
| $site['protocol'] = empty($_SERVER['HTTPS']) ? 'http' : 'https'; $site['using_ssl'] = ($site['protocol'] === 'https') ? TRUE : FALSE; $site['domain'] = 'service.x.nl'; $site['web_path'] = '/beheer/'; $site['url'] = $site['protocol'].'://'.$site['domain'].$site['web_path']; $site['cookie']['name'] = 'mc_controlpanel'; $site['cookie']['lifetime'] = 10; // in minutes $site['cookie']['httponly'] = TRUE; ini_set('session.gc_maxlifetime', $site['cookie']['lifetime']*60); ini_set('session.gc_divisor', '1'); ini_set('session.gc_probability', '1'); |
Bij het inloggen zet ik de sessie:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| session_name($site['cookie']['name']); $session_started = session_start(); $cookie_set = setcookie(session_name(), session_id(), time()+$site['cookie']['lifetime']*60, $site['web_path'], $site['domain'], $site['using_ssl'], $site['cookie']['httponly']); if ($session_started && $cookie_set) { // zetten van enkele $_SESSION vars en een redirect met header('Location: '.$site['web_path'].'start.php'); } |
Daarna, bij iedere request voor een beschermde pagina:
PHP:
1
2
3
4
5
6
7
8
9
| session_name($site['cookie']['name']); $session_started = session_start(); if ($session_started) { // lezen enkele $_SESSION vars, indien OK: serveer beschermde pagina } else { header('Location: '.$site['web_path'].'loguit.php'); exit(); } |
loguit.php:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| session_name($site['cookie']['name']); session_start(); /* Set lifetime for cookie to Jan 1, 1970, 8:00:01AM, so it'll get destroyed immediately. If expire is not set, cookie will remain in memory until browser is closed. */ $cookie_set = setcookie(session_name(), session_id(), 1, $site['web_path'], $site['domain'], $site['using_ssl'], $site['cookie']['httponly']); $session_destroyed = session_destroy(); if ($cookie_set && $session_destroyed) { // "u bent uitgelogd" } else { // niet uitgelogd, foutafhandeling } |
Gezien de gc_divisor en gc_probability beide 1 zijn, is er iets mis met mijn denkwijze?