Veuillez noter qu'au moins deux paramètres sont essentiels pour définir l'heure de la session, et peut-être trois. Les deux certainement cruciaux sont session.gc_maxlifetime et session.cookie_lifetime (où 0 n'est pas la même chose qu'un certain nombre long). Pour une certitude complète et à 100% d'autoriser de longs délais, il peut également être nécessaire de définir session.save_path, en raison de la variation du temps de nettoyage contrôlé par le système d'exploitation dans le répertoire / tmp où les fichiers de session sont stockés par défaut.
Kzqai
1
Je ne comprends pas pourquoi vous souhaitez expirer la session. Si vous craignez que l'utilisateur quitte son ordinateur sans se déconnecter et qu'un utilisateur non autorisé prenne le contrôle de son ordinateur, l'expiration de la session sur votre site n'empêchera pas le pirate de l'air d'accéder aux fichiers de la victime sur le disque.
Gqqnbig
Ce n'est pas clair ce que vous demandez ici. Voulez-vous dire que vous souhaitez implémenter un délai d'inactivité dur (actuellement PHP vous laissera volontiers utiliser une session qui n'a pas été touchée depuis plus de session.gc_maxlifetime) ou voulez-vous dire que vous voulez limiter la session à 30 minutes indépendamment de inactivité? Franchement, je pense que la réponse acceptée ici est un mauvais conseil pour l'un ou l'autre problème - dans les deux cas, la logique devrait être implémentée avec un gestionnaire de session personnalisé.
symcbean
Réponses:
1663
Vous devez implémenter votre propre délai d'expiration de session. Les deux options mentionnées par d'autres ( session.gc_maxlifetime et session.cookie_lifetime ) ne sont pas fiables. Je vais vous expliquer les raisons de cela.
Première:
session.gc_maxlifetime session.gc_maxlifetime spécifie le nombre de secondes après lesquelles les données seront considérées comme des «ordures» et nettoyées. Le garbage collection se produit au début de la session.
Mais le garbage collector n'est démarré qu'avec une probabilité de session.gc_probability divisée par session.gc_divisor . Et en utilisant les valeurs par défaut pour ces options (1 et 100 respectivement), la chance n'est que de 1%.
Eh bien, vous pouvez simplement ajuster ces valeurs pour que le garbage collector soit démarré plus souvent. Mais lorsque le garbage collector est démarré, il vérifie la validité de chaque session enregistrée. Et cela coûte cher.
De plus, lorsque vous utilisez les fichiers session.save_handler par défaut de PHP , les données de session sont stockées dans des fichiers dans un chemin spécifié dans session.save_path . Avec ce gestionnaire de session, l'âge des données de session est calculé à la dernière date de modification du fichier et non à la dernière date d'accès:
Remarque: Si vous utilisez le gestionnaire de session basé sur des fichiers par défaut, votre système de fichiers doit garder une trace des temps d'accès (atime). Windows FAT ne le fait pas, vous devrez donc trouver une autre façon de gérer le ramasse-miettes de votre session si vous êtes bloqué avec un système de fichiers FAT ou tout autre système de fichiers où le suivi atime n'est pas disponible. Depuis PHP 4.2.3, il a utilisé mtime (date modifiée) au lieu de atime. Ainsi, vous n'aurez pas de problèmes avec les systèmes de fichiers où le suivi atime n'est pas disponible.
Il peut donc en outre se produire qu'un fichier de données de session soit supprimé alors que la session elle-même est toujours considérée comme valide car les données de session n'ont pas été mises à jour récemment.
Et deuxieme:
session.cookie_lifetime session.cookie_lifetime spécifie la durée de vie du cookie en secondes qui est envoyée au navigateur. […]
Oui c'est vrai. Cela n'affecte que la durée de vie du cookie et la session elle-même peut toujours être valide. Mais c'est la tâche du serveur d'invalider une session, pas le client. Donc cela n'aide en rien. En fait, avoir session.cookie_lifetime défini sur 0ferait du cookie de la session un véritable cookie de session qui n'est valide que jusqu'à la fermeture du navigateur.
Conclusion / meilleure solution:
La meilleure solution consiste à implémenter votre propre délai d'expiration de session. Utilisez un horodatage simple qui indique l'heure de la dernière activité (c'est-à-dire la demande) et mettez-le à jour avec chaque demande:
if(isset($_SESSION['LAST_ACTIVITY'])&&(time()- $_SESSION['LAST_ACTIVITY']>1800)){// last request was more than 30 minutes ago
session_unset();// unset $_SESSION variable for the run-time
session_destroy();// destroy session data in storage}
$_SESSION['LAST_ACTIVITY']= time();// update last activity time stamp
La mise à jour des données de session à chaque demande modifie également la date de modification du fichier de session afin que la session ne soit pas supprimée prématurément par le garbage collector.
Vous pouvez également utiliser un horodatage supplémentaire pour régénérer périodiquement l'ID de session afin d'éviter des attaques sur des sessions telles que la fixation de session :
if(!isset($_SESSION['CREATED'])){
$_SESSION['CREATED']= time();}elseif(time()- $_SESSION['CREATED']>1800){// session started more than 30 minutes ago
session_regenerate_id(true);// change session ID for the current session and invalidate old session ID
$_SESSION['CREATED']= time();// update creation time}
Remarques:
session.gc_maxlifetime doit être au moins égal à la durée de vie de ce gestionnaire d'expiration personnalisé (1800 dans cet exemple);
si vous souhaitez expirer la session après 30 minutes d' activité au lieu de 30 minutes depuis le début , vous devrez également utiliser setcookieavec une expiration de time()+60*30pour conserver le cookie de session actif.
Comment pourriez-vous modifier cela si vous vouliez vérifier le «temps inactif»? En d'autres termes, l'utilisateur se connecte et tant qu'il continue à utiliser le site, il ne le déconnecte pas. Cependant, s'ils sont inactifs pendant 30 minutes, cela les déconnectera-t-il?
Metropolis
14
@Metropolis: utilisez quelque chose comme $_SESSION['LAST_ACTIVITY']similaire à l' $_SESSION['CREATED']endroit où vous stockez l'heure de la dernière activité de l'utilisateur, mais mettez à jour cette valeur à chaque demande. Maintenant, si la différence de cette heure à l'heure actuelle est supérieure à 1800 secondes, la session n'a pas été utilisée pendant plus de 30 minutes.
Gumbo
3
@Metropolis: session_unsetfait la même chose que $_SESSION = array().
Gumbo
14
@Gumbo - Je suis un peu confus, ne devriez-vous pas utiliser votre code en combinaison avec ini_set('session.gc-maxlifetime', 1800)? Sinon, vos informations de session pourraient être détruites alors que votre session est toujours censée être valide, au moins si le paramètre ini est le standard de 24 minutes. Ou est-ce que je manque quelque chose?
jeroen
10
@jeron: Oui, vous devriez. Mais notez que session.gc_maxlifetime dépend de la dernière date de modification du fichier si le gestionnaire de sauvegarde de session filesest utilisé. La session.gc_maxlifetime doit donc être au moins égale à la durée de vie de ce gestionnaire d'expiration personnalisé.
Gumbo
135
Moyen simple d'expiration de la session PHP en 30 minutes.
Remarque: si vous voulez changer l'heure, changez simplement le 30 avec l'heure souhaitée et ne changez pas * 60: cela donnera les minutes.
En minutes: (30 * 60)
En jours: (n * 24 * 60 * 60) n = nombre de jours
Login.php
<?php
session_start();?><html><formname="form1"method="post"><table><tr><td>Username</td><td><inputtype="text"name="text"></td></tr><tr><td>Password</td><td><inputtype="password"name="pwd"></td></tr><tr><td><inputtype="submit"value="SignIn"name="submit"></td></tr></table></form></html><?php
if(isset($_POST['submit'])){
$v1 ="FirstUser";
$v2 ="MyPassword";
$v3 = $_POST['text'];
$v4 = $_POST['pwd'];if($v1 == $v3 && $v2 == $v4){
$_SESSION['luser']= $v1;
$_SESSION['start']= time();// Taking now logged in time.// Ending a session in 30 minutes from the starting time.
$_SESSION['expire']= $_SESSION['start']+(30*60);
header('Location: http://localhost/somefolder/homepage.php');}else{
echo "Please enter the username or password again!";}}?>
HomePage.php
<?php
session_start();if(!isset($_SESSION['luser'])){
echo "Please Login again";
echo "<a href='http://localhost/somefolder/login.php'>Click Here to Login</a>";}else{
$now = time();// Checking the time now when home page starts.if($now > $_SESSION['expire']){
session_destroy();
echo "Your session has expired! <a href='http://localhost/somefolder/login.php'>Login here</a>";}else{//Starting this else one [else1]?><!-- From here all HTML coding can be done --><html>
Welcome
<?php
echo $_SESSION['luser'];
echo "<a href='http://localhost/somefolder/logout.php'>Log out</a>";?></html><?php
}}?>
La combinaison de la logique et de la présentation est mal conseillée de nos jours où le MVC est la norme.
bcosca
Peut-être que je manque quelque chose d'élémentaire sur les sessions, mais à quoi cela sert-il si les sessions sont détruites toutes les 30 minutes par le système d'exploitation?
25
@stillstanding Parlez pour vous [sourire] Je considère MVC comme une abomination.
2
MVC est-il une bonne idée même lorsque le projet est petit, avec un seul programmeur? J'ai l'impression que je devrais faire mes propres projets dans le modèle MVC (ou résoudre le problème ALORS en faire MVC) mais avec un manque d'expérience avec MVC cela devient juste un blocage mental "Comment puis-je faire ce MVC?" et une distraction de l'objectif / problème initial nécessitant une solution.
MrVimes
@ encore une autre mention est que les en- Login.phptêtes sont envoyés APRÈS le contenu, ce qui est mauvais.
machineaddict
43
Est-ce pour déconnecter l'utilisateur après un temps défini? Définir l'heure de création de la session (ou une heure d'expiration) lors de son enregistrement, puis vérifier que sur chaque chargement de page pourrait gérer cela.
session.gc-maxlifetime est probablement la meilleure solution.
Powerlord
2
Il y a quelques problèmes avec la durée de vie du cookie de session, notamment, il dépend du client pour l'appliquer. La durée de vie du cookie est là pour permettre au client de nettoyer les cookies inutiles / expirés, il ne doit pas être confondu avec quoi que ce soit lié à la sécurité.
Jacco
Est-ce gc_maxlifetimeou gc-maxlifetime. Prend-il en charge les traits de soulignement et les tirets?
À mon humble avis, la deuxième option est une bonne solution:
<?php
/***
* Starts a session with a specific timeout and a specific GC probability.
* @param int $timeout The number of seconds until it should time out.
* @param int $probability The probablity, in int percentage, that the garbage
* collection routine will be triggered right now.
* @param strint $cookie_domain The domain path for the cookie.
*/function session_start_timeout($timeout=5, $probability=100, $cookie_domain='/'){// Set the max lifetime
ini_set("session.gc_maxlifetime", $timeout);// Set the session cookie to timout
ini_set("session.cookie_lifetime", $timeout);// Change the save path. Sessions stored in teh same path// all share the same lifetime; the lowest lifetime will be// used for all. Therefore, for this to work, the session// must be stored in a directory where only sessions sharing// it's lifetime are. Best to just dynamically create on.
$seperator = strstr(strtoupper(substr(PHP_OS,0,3)),"WIN")?"\\":"/";
$path = ini_get("session.save_path"). $seperator ."session_". $timeout ."sec";if(!file_exists($path)){if(!mkdir($path,600)){
trigger_error("Failed to create session save path directory '$path'. Check permissions.", E_USER_ERROR);}}
ini_set("session.save_path", $path);// Set the chance to trigger the garbage collection.
ini_set("session.gc_probability", $probability);
ini_set("session.gc_divisor",100);// Should always be 100// Start the session!
session_start();// Renew the time left until this session times out.// If you skip this, the session will time out based// on the time when it was created, rather than when// it was last used.if(isset($_COOKIE[session_name()])){
setcookie(session_name(), $_COOKIE[session_name()], time()+ $timeout, $cookie_domain);}}
Eh bien, je comprends que les réponses ci-dessus sont correctes, mais elles sont au niveau de l'application, pourquoi ne pas simplement utiliser le .htaccessfichier pour définir le délai d'expiration?
C'est en fait facile avec une fonction comme la suivante. Il utilise le nom de table de base de données «sessions» avec les champs «id» et «time».
Chaque fois que l'utilisateur visite à nouveau votre site ou service, vous devez invoquer cette fonction pour vérifier si sa valeur de retour est VRAIE. Si elle est FAUX, l'utilisateur a expiré et la session sera détruite (Remarque: cette fonction utilise une classe de base de données pour se connecter et interroger la base de données, bien sûr, vous pouvez également le faire à l'intérieur de votre fonction ou quelque chose comme ça):
function session_timeout_ok(){global $db;
$timeout = SESSION_TIMEOUT;//const, e.g. 6 * 60 for 6 minutes
$ok =false;
$session_id = session_id();
$sql ="SELECT time FROM sessions WHERE session_id = '".$session_id."'";
$rows = $db->query($sql);if($rows ===false){//Timestamp could not be read
$ok = FALSE;}else{//Timestamp was read succesfullyif(count($rows)>0){
$zeile = $rows[0];
$time_past = $zeile['time'];if( $timeout + $time_past < time()){//Time has expired
session_destroy();
$sql ="DELETE FROM sessions WHERE session_id = '". $session_id ."'";
$affected = $db -> query($sql);
$ok = FALSE;}else{//Time is okay
$ok = TRUE;
$sql ="UPDATE sessions SET time='". time()."' WHERE session_id = '". $session_id ."'";
$erg = $db -> query($sql);if($erg ==false){//DB error}}}else{//Session is new, write it to database table sessions
$sql ="INSERT INTO sessions(session_id,time) VALUES ('".$session_id."','".time()."')";
$res = $db->query($sql);if($res === FALSE){//Database error
$ok =false;}
$ok =true;}return $ok;}return $ok;}
<?php
$user = $_POST['user_name'];
$pass = $_POST['user_pass'];require('db_connection.php');// Hey, always escape input if necessary!
$result = mysql_query(sprintf("SELECT * FROM accounts WHERE user_Name='%s' AND user_Pass='%s'", mysql_real_escape_string($user), mysql_real_escape_string($pass));if( mysql_num_rows( $result )>0){
$array = mysql_fetch_assoc($result);
session_start();
$_SESSION['user_id']= $user;
$_SESSION['login_time']= time();
header("Location:loggedin.php");}else{
header("Location:login.php");}?>
Maintenant, vérifiez si l'horodatage est dans la fenêtre de temps autorisée (1800 secondes soit 30 minutes)
<?php
session_start();if(!isset( $_SESSION['user_id'])|| time()- $_SESSION['login_time']>1800){
header("Location:login.php");}else{// uncomment the next line to refresh the session, so it will expire after thirteen minutes of inactivity, and not thirteen minutes after login//$_SESSION['login_time'] = time();
echo ("this session is ". $_SESSION['user_id']);//show rest of the page and all other content}?>
Vous pouvez directement utiliser une base de données pour le faire comme alternative. J'utilise une fonction DB pour ce faire que j'appelle chk_lgn.
Vérifiez les vérifications de connexion pour voir si elles sont connectées ou non et, ce faisant, elle définit l'horodatage de la date du dernier contrôle comme actif dans la ligne / colonne db de l'utilisateur.
J'y fais aussi le contrôle horaire. Cela fonctionne pour moi pour le moment car j'utilise cette fonction pour chaque page.
PS Personne que j'avais vu n'avait suggéré une solution DB pure.
Réponses:
Vous devez implémenter votre propre délai d'expiration de session. Les deux options mentionnées par d'autres ( session.gc_maxlifetime et session.cookie_lifetime ) ne sont pas fiables. Je vais vous expliquer les raisons de cela.
Première:
Mais le garbage collector n'est démarré qu'avec une probabilité de session.gc_probability divisée par session.gc_divisor . Et en utilisant les valeurs par défaut pour ces options (1 et 100 respectivement), la chance n'est que de 1%.
Eh bien, vous pouvez simplement ajuster ces valeurs pour que le garbage collector soit démarré plus souvent. Mais lorsque le garbage collector est démarré, il vérifie la validité de chaque session enregistrée. Et cela coûte cher.
De plus, lorsque vous utilisez les fichiers session.save_handler par défaut de PHP , les données de session sont stockées dans des fichiers dans un chemin spécifié dans session.save_path . Avec ce gestionnaire de session, l'âge des données de session est calculé à la dernière date de modification du fichier et non à la dernière date d'accès:
Il peut donc en outre se produire qu'un fichier de données de session soit supprimé alors que la session elle-même est toujours considérée comme valide car les données de session n'ont pas été mises à jour récemment.
Et deuxieme:
Oui c'est vrai. Cela n'affecte que la durée de vie du cookie et la session elle-même peut toujours être valide. Mais c'est la tâche du serveur d'invalider une session, pas le client. Donc cela n'aide en rien. En fait, avoir session.cookie_lifetime défini sur
0
ferait du cookie de la session un véritable cookie de session qui n'est valide que jusqu'à la fermeture du navigateur.Conclusion / meilleure solution:
La meilleure solution consiste à implémenter votre propre délai d'expiration de session. Utilisez un horodatage simple qui indique l'heure de la dernière activité (c'est-à-dire la demande) et mettez-le à jour avec chaque demande:
La mise à jour des données de session à chaque demande modifie également la date de modification du fichier de session afin que la session ne soit pas supprimée prématurément par le garbage collector.
Vous pouvez également utiliser un horodatage supplémentaire pour régénérer périodiquement l'ID de session afin d'éviter des attaques sur des sessions telles que la fixation de session :
Remarques:
session.gc_maxlifetime
doit être au moins égal à la durée de vie de ce gestionnaire d'expiration personnalisé (1800 dans cet exemple);setcookie
avec une expiration detime()+60*30
pour conserver le cookie de session actif.la source
$_SESSION['LAST_ACTIVITY']
similaire à l'$_SESSION['CREATED']
endroit où vous stockez l'heure de la dernière activité de l'utilisateur, mais mettez à jour cette valeur à chaque demande. Maintenant, si la différence de cette heure à l'heure actuelle est supérieure à 1800 secondes, la session n'a pas été utilisée pendant plus de 30 minutes.session_unset
fait la même chose que$_SESSION = array()
.ini_set('session.gc-maxlifetime', 1800)
? Sinon, vos informations de session pourraient être détruites alors que votre session est toujours censée être valide, au moins si le paramètre ini est le standard de 24 minutes. Ou est-ce que je manque quelque chose?files
est utilisé. La session.gc_maxlifetime doit donc être au moins égale à la durée de vie de ce gestionnaire d'expiration personnalisé.Moyen simple d'expiration de la session PHP en 30 minutes.
Remarque: si vous voulez changer l'heure, changez simplement le 30 avec l'heure souhaitée et ne changez pas * 60: cela donnera les minutes.
En minutes: (30 * 60)
En jours: (n * 24 * 60 * 60) n = nombre de jours
Login.php
HomePage.php
LogOut.php
la source
Login.php
têtes sont envoyés APRÈS le contenu, ce qui est mauvais.Est-ce pour déconnecter l'utilisateur après un temps défini? Définir l'heure de création de la session (ou une heure d'expiration) lors de son enregistrement, puis vérifier que sur chaque chargement de page pourrait gérer cela.
Par exemple:
Edit: J'ai le sentiment que vous voulez dire autre chose cependant.
Vous pouvez supprimer des sessions après une certaine durée de vie en utilisant le
session.gc_maxlifetime
paramètre ini:Edit: ini_set ('session.gc_maxlifetime', 60 * 30);
la source
gc_maxlifetime
ougc-maxlifetime
. Prend-il en charge les traits de soulignement et les tirets?Cette publication montre quelques façons de contrôler le délai d'expiration de la session: http://bytes.com/topic/php/insights/889606-setting-timeout-php-sessions
À mon humble avis, la deuxième option est une bonne solution:
la source
Eh bien, je comprends que les réponses ci-dessus sont correctes, mais elles sont au niveau de l'application, pourquoi ne pas simplement utiliser le
.htaccess
fichier pour définir le délai d'expiration?la source
la source
Utilisez le
session_set_cookie_params
fonction pour faire cela.Est nécessaire d'appeler cette fonction avant l'
session_start()
appel.Essaye ça:
Voir plus dans: http://php.net/manual/function.session-set-cookie-params.php
la source
C'est en fait facile avec une fonction comme la suivante. Il utilise le nom de table de base de données «sessions» avec les champs «id» et «time».
Chaque fois que l'utilisateur visite à nouveau votre site ou service, vous devez invoquer cette fonction pour vérifier si sa valeur de retour est VRAIE. Si elle est FAUX, l'utilisateur a expiré et la session sera détruite (Remarque: cette fonction utilise une classe de base de données pour se connecter et interroger la base de données, bien sûr, vous pouvez également le faire à l'intérieur de votre fonction ou quelque chose comme ça):
la source
Enregistrer un horodatage dans la session
Maintenant, vérifiez si l'horodatage est dans la fenêtre de temps autorisée (1800 secondes soit 30 minutes)
la source
Veuillez utiliser le bloc de code suivant dans votre fichier include qui s'est chargé dans toutes les pages.
la source
Utilisez cette classe pendant 30 min
la source
Utilisation de l'horodatage ...
J'ai utilisé 20 secondes pour expirer la session en utilisant l'horodatage .
Si vous avez besoin de 30 min, ajoutez 1800 (30 min en secondes) ...
la source
Vous pouvez directement utiliser une base de données pour le faire comme alternative. J'utilise une fonction DB pour ce faire que j'appelle chk_lgn.
Vérifiez les vérifications de connexion pour voir si elles sont connectées ou non et, ce faisant, elle définit l'horodatage de la date du dernier contrôle comme actif dans la ligne / colonne db de l'utilisateur.
J'y fais aussi le contrôle horaire. Cela fonctionne pour moi pour le moment car j'utilise cette fonction pour chaque page.
PS Personne que j'avais vu n'avait suggéré une solution DB pure.
la source
La façon dont PHP gère les sessions est assez déroutante pour les débutants. Cela pourrait les aider en donnant un aperçu du fonctionnement des sessions: fonctionnement des sessions (gestionnaires de sessions personnalisés)
la source
Il suffit de stocker l'heure actuelle et si elle dépasse 30 minutes en comparant puis détruisez la session en cours.
la source