Observe que pelo menos duas configurações são cruciais para definir o tempo da sessão e talvez três. Os dois certamente cruciais são session.gc_maxlifetime e session.cookie_lifetime (onde 0 não é o mesmo que um número longo). Para ter 100% de certeza de permitir longos períodos, também pode ser necessário definir o session.save_path, devido à variação do tempo de limpeza controlado pelo SO no diretório / tmp em que os arquivos de sessão são armazenados por padrão.
Kzqai
1
Não entendo por que você deseja expirar a sessão. Se você se preocupa que o usuário saia do computador sem fazer logout e um usuário não autorizado o controle, a expiração da sessão no site não impedirá que o seqüestrador acesse os arquivos da vítima no disco.
precisa saber é o seguinte
Não está claro o que você está perguntando aqui. Você quer dizer que deseja implementar um tempo limite de inatividade difícil (atualmente o PHP permite que você use uma sessão que não foi tocada por mais que session.gc_maxlifetime) ou quer limitar a sessão a 30 minutos, independentemente de inatividade? Francamente, acho que a resposta aceita aqui é um péssimo conselho para qualquer um dos problemas - em ambos os casos, a lógica deve ser implementada com um manipulador de sessão personalizado.
19418 sycbean
Respostas:
1663
Você deve implementar seu próprio tempo limite da sessão. Ambas as opções mencionadas por outras pessoas ( session.gc_maxlifetime e session.cookie_lifetime ) não são confiáveis. Eu vou explicar as razões para isso.
Primeiro:
session.gc_maxlifetime session.gc_maxlifetime especifica o número de segundos após os quais os dados serão vistos como 'lixo' e limpos. A coleta de lixo ocorre durante o início da sessão.
Mas o coletor de lixo é iniciado apenas com uma probabilidade de session.gc_probability dividida por session.gc_divisor . E usando os valores padrão para essas opções (1 e 100 respectivamente), a chance é de apenas 1%.
Bem, você pode simplesmente ajustar esses valores para que o coletor de lixo seja iniciado com mais frequência. Mas quando o coletor de lixo é iniciado, ele verifica a validade de cada sessão registrada. E isso custa muito.
Além disso, ao usar os arquivos session.save_handler padrão do PHP , os dados da sessão são armazenados nos arquivos em um caminho especificado em session.save_path . Com esse manipulador de sessão, a idade dos dados da sessão é calculada na data da última modificação do arquivo e não na data do último acesso:
Nota: Se você estiver usando o manipulador de sessões baseado em arquivo padrão, seu sistema de arquivos deve acompanhar os tempos de acesso (atime). O Windows FAT não funciona, portanto você terá que criar outra maneira de lidar com a coleta de lixo da sua sessão, se você estiver com um sistema de arquivos FAT ou qualquer outro sistema de arquivos em que o rastreamento de atime não esteja disponível. Desde o PHP 4.2.3, ele usa mtime (data de modificação) em vez de atime. Portanto, você não terá problemas com sistemas de arquivos nos quais o atime tracking não está disponível.
Portanto, adicionalmente, pode ocorrer que um arquivo de dados da sessão seja excluído enquanto a própria sessão ainda é considerada válida porque os dados da sessão não foram atualizados recentemente.
E em segundo lugar:
session.cookie_lifetime session.cookie_lifetime especifica o tempo de vida do cookie em segundos, que é enviado ao navegador. [...]
Sim está certo. Isso afeta apenas a vida útil do cookie e a própria sessão ainda pode ser válida. Mas é tarefa do servidor invalidar uma sessão, não o cliente. Então isso não ajuda em nada. De fato, ter session.cookie_lifetime definido como 0tornaria o cookie da sessão um cookie de sessão real , válido apenas até o navegador ser fechado.
Conclusão / melhor solução:
A melhor solução é implementar seu próprio tempo limite de sessão. Use um registro de data e hora simples que indique a hora da última atividade (ou seja, solicitação) e atualize-a com cada solicitação:
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
A atualização dos dados da sessão com cada solicitação também altera a data de modificação do arquivo da sessão, para que a sessão não seja removida pelo coletor de lixo prematuramente.
Você também pode usar um carimbo de data / hora adicional para gerar novamente o ID da sessão periodicamente para evitar ataques a sessões como a fixação da sessão :
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}
Notas:
session.gc_maxlifetime deve ser pelo menos igual ao tempo de vida desse manipulador de expiração personalizado (1800 neste exemplo);
se você quiser expirar a sessão após 30 minutos de atividade, em vez de após 30 minutos desde o início , também precisará usar setcookiecom um prazo de validade time()+60*30para manter o cookie da sessão ativo.
Como você pode alterar isso se quiser verificar o "tempo inativo"? Em outras palavras, o usuário efetua login e, enquanto continuar usando o site, ele não será desconectado. No entanto, se ficarem inativos por 30 minutos, eles serão desconectados?
Metropolis
14
@ Metropolis: use algo $_SESSION['LAST_ACTIVITY']parecido com o local $_SESSION['CREATED']onde você armazena o horário da última atividade do usuário, mas atualize esse valor a cada solicitação. Agora, se a diferença desse tempo para o tempo atual for maior que 1800 segundos, a sessão não será usada por mais de 30 minutos.
Gumbo
3
@ Metropolis: session_unsetfaz o mesmo que $_SESSION = array().
Gumbo
14
@ Gumbo - Estou um pouco confuso, você não deveria usar seu código em combinação com ini_set('session.gc-maxlifetime', 1800)? Caso contrário, as informações da sua sessão poderão ser destruídas enquanto a sua sessão ainda é válida, pelo menos se a configuração ini for o padrão de 24 minutos. Ou eu estou esquecendo de alguma coisa?
jeroen
10
@ jeron: Sim, você deveria. Mas observe que session.gc_maxlifetime depende da data da última modificação do arquivo se o manipulador de salvamento da sessão filesfor usado. Portanto, session.gc_maxlifetime deve ser pelo menos igual ao tempo de vida desse manipulador de expiração personalizado.
Gumbo
135
Maneira simples de expirar a sessão do PHP em 30 minutos.
Nota: se você quiser alterar a hora, basta alterar a 30 com a hora desejada e não altere * 60: isso fornecerá os minutos.
Em minutos: (30 * 60)
Em dias: (n * 24 * 60 * 60) n = não de dias
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><?phpif(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}}?>
Combinar lógica e apresentação não é aconselhável atualmente, quando o MVC é a norma.
bcosca
Talvez eu esteja perdendo algo elementar sobre as sessões, mas que benefício isso faz se as sessões são destruídas a cada 30 minutos pelo sistema operacional?
25
@stillstanding Fale por si [sorriso] Eu vejo o MVC como uma abominação.
2
O MVC é uma boa ideia, mesmo quando o projeto é pequeno, com um único programador? Eu sinto que deveria estar fazendo meus próprios projetos no modelo MVC (ou resolver o problema ENTÃO torná-lo MVC), mas com a falta de experiência com o MVC, isso se torna um bloqueio mental "Como faço para criar este MVC?" e uma distração do objetivo / problema inicial que requer uma solução.
MrVimes 27/07/18
@ ainda outra menção é que nos Login.phpcabeçalhos são enviados APÓS o conteúdo, o que é ruim.
precisa
43
Isso é para desconectar o usuário após um tempo definido? Definir o tempo de criação da sessão (ou um tempo de expiração) quando ele é registrado e, em seguida, verificar se o carregamento de cada página pode lidar com isso.
session.gc-maxlifetime é provavelmente o melhor caminho a percorrer.
Powerlord
2
Há alguns problemas com a vida útil do cookie de sessão, principalmente, ele depende do cliente para aplicá-lo. A vida útil do cookie existe para permitir que o cliente limpe cookies inúteis / expirados, não deve ser confundida com nada relacionado à segurança.
Jacco 15/05
É gc_maxlifetimeou gc-maxlifetime. Ele suporta sublinhados e hífens?
<?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);}}
Bem, eu entendo que as respostas acima estão corretas, mas estão no nível do aplicativo. Por que simplesmente não usamos o .htaccessarquivo para definir o tempo de expiração?
Na verdade, é fácil com uma função como a seguinte. Ele usa o nome da tabela de banco de dados 'sessões' com os campos 'id' e 'time'.
Sempre que o usuário visitar seu site ou serviço novamente, você deverá chamar esta função para verificar se o valor de retorno é VERDADEIRO. Se for FALSE, o usuário expirou e a sessão será destruída.
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");}?>
Agora, verifique se o registro de data e hora está dentro da janela de tempo permitido (1800 segundos é 30 minutos)
<?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}?>
Você pode usar diretamente um banco de dados para fazer isso como uma alternativa. Eu uso uma função DB para fazer isso que chamo de chk_lgn.
Verifique as verificações de login para ver se elas estão conectadas ou não e, ao fazer isso, define o registro de data e hora da verificação como a última atividade na linha / coluna db do usuário.
Eu também faço a verificação do tempo lá. Isso funciona para mim no momento, pois uso essa função para todas as páginas.
PS: Ninguém que eu tinha visto sugerira uma solução pura de banco de dados.
Respostas:
Você deve implementar seu próprio tempo limite da sessão. Ambas as opções mencionadas por outras pessoas ( session.gc_maxlifetime e session.cookie_lifetime ) não são confiáveis. Eu vou explicar as razões para isso.
Primeiro:
Mas o coletor de lixo é iniciado apenas com uma probabilidade de session.gc_probability dividida por session.gc_divisor . E usando os valores padrão para essas opções (1 e 100 respectivamente), a chance é de apenas 1%.
Bem, você pode simplesmente ajustar esses valores para que o coletor de lixo seja iniciado com mais frequência. Mas quando o coletor de lixo é iniciado, ele verifica a validade de cada sessão registrada. E isso custa muito.
Além disso, ao usar os arquivos session.save_handler padrão do PHP , os dados da sessão são armazenados nos arquivos em um caminho especificado em session.save_path . Com esse manipulador de sessão, a idade dos dados da sessão é calculada na data da última modificação do arquivo e não na data do último acesso:
Portanto, adicionalmente, pode ocorrer que um arquivo de dados da sessão seja excluído enquanto a própria sessão ainda é considerada válida porque os dados da sessão não foram atualizados recentemente.
E em segundo lugar:
Sim está certo. Isso afeta apenas a vida útil do cookie e a própria sessão ainda pode ser válida. Mas é tarefa do servidor invalidar uma sessão, não o cliente. Então isso não ajuda em nada. De fato, ter session.cookie_lifetime definido como
0
tornaria o cookie da sessão um cookie de sessão real , válido apenas até o navegador ser fechado.Conclusão / melhor solução:
A melhor solução é implementar seu próprio tempo limite de sessão. Use um registro de data e hora simples que indique a hora da última atividade (ou seja, solicitação) e atualize-a com cada solicitação:
A atualização dos dados da sessão com cada solicitação também altera a data de modificação do arquivo da sessão, para que a sessão não seja removida pelo coletor de lixo prematuramente.
Você também pode usar um carimbo de data / hora adicional para gerar novamente o ID da sessão periodicamente para evitar ataques a sessões como a fixação da sessão :
Notas:
session.gc_maxlifetime
deve ser pelo menos igual ao tempo de vida desse manipulador de expiração personalizado (1800 neste exemplo);setcookie
com um prazo de validadetime()+60*30
para manter o cookie da sessão ativo.fonte
$_SESSION['LAST_ACTIVITY']
parecido com o local$_SESSION['CREATED']
onde você armazena o horário da última atividade do usuário, mas atualize esse valor a cada solicitação. Agora, se a diferença desse tempo para o tempo atual for maior que 1800 segundos, a sessão não será usada por mais de 30 minutos.session_unset
faz o mesmo que$_SESSION = array()
.ini_set('session.gc-maxlifetime', 1800)
? Caso contrário, as informações da sua sessão poderão ser destruídas enquanto a sua sessão ainda é válida, pelo menos se a configuração ini for o padrão de 24 minutos. Ou eu estou esquecendo de alguma coisa?files
for usado. Portanto, session.gc_maxlifetime deve ser pelo menos igual ao tempo de vida desse manipulador de expiração personalizado.Maneira simples de expirar a sessão do PHP em 30 minutos.
Nota: se você quiser alterar a hora, basta alterar a 30 com a hora desejada e não altere * 60: isso fornecerá os minutos.
Em minutos: (30 * 60)
Em dias: (n * 24 * 60 * 60) n = não de dias
Login.php
HomePage.php
LogOut.php
fonte
Login.php
cabeçalhos são enviados APÓS o conteúdo, o que é ruim.Isso é para desconectar o usuário após um tempo definido? Definir o tempo de criação da sessão (ou um tempo de expiração) quando ele é registrado e, em seguida, verificar se o carregamento de cada página pode lidar com isso.
Por exemplo:
Edit: Eu tenho a sensação de que você quer dizer outra coisa.
Você pode descartar sessões após uma certa vida útil, usando a
session.gc_maxlifetime
configuração ini:Edit: ini_set ('session.gc_maxlifetime', 60 * 30);
fonte
gc_maxlifetime
ougc-maxlifetime
. Ele suporta sublinhados e hífens?Esta postagem mostra algumas maneiras de controlar o tempo limite da sessão: http://bytes.com/topic/php/insights/889606-setting-timeout-php-sessions
IMHO a segunda opção é uma boa solução:
fonte
Bem, eu entendo que as respostas acima estão corretas, mas estão no nível do aplicativo. Por que simplesmente não usamos o
.htaccess
arquivo para definir o tempo de expiração?fonte
fonte
Use a função
session_set_cookie_params
para fazer isso.É necessário chamar esta função antes da
session_start()
chamada.Tente o seguinte:
Veja mais em: http://php.net/manual/function.session-set-cookie-params.php
fonte
Na verdade, é fácil com uma função como a seguinte. Ele usa o nome da tabela de banco de dados 'sessões' com os campos 'id' e 'time'.
Sempre que o usuário visitar seu site ou serviço novamente, você deverá chamar esta função para verificar se o valor de retorno é VERDADEIRO. Se for FALSE, o usuário expirou e a sessão será destruída.
fonte
Armazenar um carimbo de data / hora na sessão
Agora, verifique se o registro de data e hora está dentro da janela de tempo permitido (1800 segundos é 30 minutos)
fonte
Use o seguinte bloco de código no seu arquivo de inclusão, carregado em todas as páginas.
fonte
Use esta classe por 30 min
fonte
Usando carimbo de data e hora ...
Eu usei 20 segundos para expirar a sessão usando o carimbo de data / hora .
Se precisar de 30 min, adicione 1800 (30 min em segundos) ...
fonte
Você pode usar diretamente um banco de dados para fazer isso como uma alternativa. Eu uso uma função DB para fazer isso que chamo de chk_lgn.
Verifique as verificações de login para ver se elas estão conectadas ou não e, ao fazer isso, define o registro de data e hora da verificação como a última atividade na linha / coluna db do usuário.
Eu também faço a verificação do tempo lá. Isso funciona para mim no momento, pois uso essa função para todas as páginas.
PS: Ninguém que eu tinha visto sugerira uma solução pura de banco de dados.
fonte
Como o PHP lida com as sessões é bastante confuso para os iniciantes entenderem. Isso pode ajudá-los, fornecendo uma visão geral de como as sessões funcionam: como as sessões funcionam (manipuladores de sessão personalizados)
fonte
Apenas armazene o horário atual e, se exceder 30 minutos, comparando, destrua a sessão atual.
fonte