I'm currently working on a simple Authentification system and i'm using PHP Sessions.
In my header of every page i have a bit of PHP that does 3 things:
If the session last used time is older than 30 minutes it's destroyed
If the session last used time is older than 5 minutes it's regenerated
If the ips are not the same in the same session it's destroyed
However it doesn't seem to wok for the IP.
It gives me the error Undefined Index when i use isset to check if it is initialized or not.
session_start();
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
}
if (!isset($_SESSION['CREATED'])) {
$_SESSION['CREATED'] = time();
} else if (time() - $_SESSION['CREATED'] > 900) {
// 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
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp
//GET CHECK IP
if (!isset($_SESSION['ADDR'])) {
if ($_SESSION['ADDR'] != get_client_ip()){
session_unset(); // unset $_SESSION variable for the run-time
session_destroy(); // destroy session data in storage
}
}else {
$_SESSION['ADDR'] = get_client_ip();
}
echo "<pre>".print_r($_SESSION)."</pre>";
You are trying to say if $_SESSION['ADDR'] has not been set. Remove the negation operator !.
if (isset($_SESSION['ADDR'])) {
// code here
}
Related
I'm trying to install COOKIES into my website.
I have found a script on GitHub: https://github.com/jotaroita/secure-login-php7-remember-register-resetpw
I have implemented the script and i'm able to login.
I'm able to login with just SESSION, or i can login with both SESSION and set a "Remember me -COOKIE".
To test the COOKIE i have set the SESSION to expire after 1 minute. $expireAfter = 1;
Senario:
I login to the website and check "remember me". Session starts and a cookie is set. Everything fine!
## last action: 1 seconds ago
skip the cookie check: session already set
I wait 60 seconds and reloads the page. Sessions destroys and Cookie reads:
## last action: 108 seconds ago
session destroy for inactivity
cookie read
cookie valid format
cookie right selector
cookie right token
set a new token in DB and in cookie
session set <- Within this message i can output Session data: $_SESSION['user'] at all times
BUT in my other page(home.php) $_SESSION['user'] is empty?! (I include the SESSION and COOKIE check from: check.php) if(isset($_SESSION['last_action'])){ returns true
If i wait another 60 seconds and reload the page if(isset($_SESSION['last_action'])){ returns false. But now the $_SESSION['user'] is set.
If i wait another 60 seconds and reload the page. if(isset($_SESSION['last_action'])){ returns true. But now the $_SESSION['user'] is empty.
home.php
<?php
//START SESSION
session_start();
//CONNECT TO DB, SET HEADER, SET TIMEZONE, CHECK FOR LOGIN-COOKIES
include("check.php");
//CHECK IF SESSION EXIST
if(!isset($_SESSION['user'])) {
$isSesstion = false;
header("Location: /index.php");
}
else{
$isSesstion = true;
}
.....
check.php
<?php
define ("PEPPER",''); //random string for extra salt, use if you want.
define ("WEBSITE",'mydomain.com'); //your web site without http:// without final /
define ("SCRIPTFOLDER",'/login'); //direcory of the script start with a / if you installed the script in the root write just a / never finish with a /
$hosting="localhost"; //your host or localhost
$database="db"; //your database name
$database_user="user"; //your username for database
$database_password="pwd"; //your database password
require_once('pdo_db.php');
//generate random sequence or numbers and letter avoid problems with special chars
function aZ ($n=12) {
$chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$bytes = random_ver($n);
$result="";
foreach (str_split($bytes) as $byte) $result .= $chars[ord($byte) % strlen($chars)];
return $result;
}
//generate random and avoid compatibility problem with php version
function random_ver ($n=10) {
$v=(int)phpversion()+0;
if ($v<7) {
//if php version < 7 use the old function for generate random bytes
return openssl_random_pseudo_bytes($n);
}else{
//random_bytes is better but works only with php version > 7
return random_bytes($n);
}
}
// ********************************
// * SESSION TIME UPDATE *
// ********************************
//Expire the session if user is inactive for 15 minutes or more.
//if u want to check how cookie works let the session id expire (wait X minutes without action, maybe set expireAfter to low value),
//close the browser then open again
$expireAfter = 1;
//Check to see if our "last action" session
//variable has been set.
if(isset($_SESSION['last_action'])){ echo 'IN';
//Figure out how many seconds have passed
//since the user was last active.
$secondsInactive = time() - $_SESSION['last_action'];
//Convert our minutes into seconds.
$expireAfterSeconds = $expireAfter * 60;
//Check to see if they have been inactive for too long.
$debug.="last action: $secondsInactive seconds ago<br>";
if($secondsInactive >= $expireAfterSeconds){
//User has been inactive for too long.
//Kill their session.
session_unset();
session_destroy();
$debug.="session destroy for inactivity<br>";
}
}
//Assign the current timestamp as the user's
//latest activity
$_SESSION['last_action'] = time();
// *********************************
// * CHECK AUTO LOG-IN WITH COOKIE *
// *********************************
//if session is not set, but cookie exists
if (empty($_SESSION['user']) && !empty($_COOKIE['remember']) && $_GET["logout"]!=1) {
$debug.="cookie read<br>";
list($selector, $authenticator) = explode(':', urldecode($_COOKIE['remember']));
//get from database the row with id and token related to selector code in the cookie
$sql = $db->prepare("SELECT * FROM user_tokens
WHERE selector = ? limit 1");
$sql->bindParam(1, $selector);
$sql->execute();
$row = $sql->fetch(PDO::FETCH_ASSOC);
if (empty($authenticator) or empty($selector))
$debug.="cookie invalid format<br>";
//continue to check the authenticator only if the selector in the cookie is present in the database
if (($sql->rowCount() > 0) && !empty($authenticator) && !empty($selector)) {
$debug.="cookie valid format<br>";
// the token provided is like the token in the database
// the functions password_verify and password_hash add secure salt and avoid timing attacks
if (password_verify(base64_decode($authenticator), $row['hashedvalidator'])){
//SET SESSION DATA
$sql = $db->prepare("SELECT * FROM users WHERE id = ?");
$sql->bindParam(1, $row['userid']);
$sql->execute();
$session_data = $sql->fetch(PDO::FETCH_ASSOC);
//UNSET VARS
unset($session_data['password']);
$_SESSION['user'] = $session_data;
//update database with a new token for the same selector and set the cookie again
$authenticator = bin2hex(random_ver(33));
$res=$db->prepare("UPDATE user_tokens SET hashedvalidator = ? , expires = FROM_UNIXTIME(".(time() + 864000*7).") , ip = ? WHERE selector = ?");
$res->execute(array(password_hash($authenticator, PASSWORD_DEFAULT, ['cost' => 12]),$_SERVER['REMOTE_ADDR'],$selector));
//set the cookie
$setc = setcookie(
'remember',
$selector.':'.base64_encode($authenticator),
time() + 864000*7, //the cookie will be valid for 7 days, or till log-out (if u want change it, modify the login.php file too)
'/',
WEBSITE,
false, // TLS-only set to true if u have a website on https://
false // http-only
);
$debug.="cookie right selector<br>cookie right token<br>set a new token in DB and in cookie<br>session set ".$_SESSION['user']['usr_fname']."<br>";
} else {
//selector exists but token doesnt match. that could be a secure problem, all selector/authenticator in database for that user will be deleted
$res=$db->prepare("DELETE FROM user_tokens WHERE userid = ".$row["userid"]);
$res->execute();
$debug.="cookie right selector<br>cookie wrong token (all DB entry for that user are deleted)<br>";
}
} else {
$debug.="selector not found in DB<br>";
}
} else {
$debug.="skip the cookie check: ";
if (!empty($_SESSION['user'])) $debug.="session already set<br>";
if (empty($_COOKIE['remember'])) $debug.="no cookie set<br>";
}
?>
So, whats wrong with the code?
Why is the $_SESSION filled with data every second time i refresh the webpage?
Why doesn't if(isset($_SESSION['last_action'])){ returns true everytime i refresh the page? And why does $_SESSION carry data in the debug message session set ".$_SESSION['user']['usr_fname']." all the time... but it is not carried over to home.php with the include(check.php"); ?
Do you need some more code? Just ask for it!
I think i found the problem.
After unset & destroy the session. I had to start a new session.
Strange thing this only happens every second time. But adding session_start(); solved the problem!
if(isset($_SESSION['last_action'])){
$secondsInactive = time() - $_SESSION['last_action'];
$expireAfterSeconds = $expireAfter * 60;
$debug.="last action: $secondsInactive seconds ago<br>";
if($secondsInactive >= $expireAfterSeconds){
//User has been inactive for too long.
//Kill their session.
session_unset();
session_destroy();
$debug.="session destroy for inactivity<br>";
}
}
...
session_start();
$_SESSION['user'] = $session_data;
...
In my web application, when i try to hit authentication service by passing username and password. Following is the code that handles authentication.
ini_set("session.cookie_lifetime","7200"); // 120 minutes
ini_set("session.gc_maxlifetime","7200"); // 120 minutes
session_start();
$_SESSION['logged_in'] = true;
$_SESSION['last_activity'] = time(); /
$_SESSION['expire_time'] = 2*60*60;
$_SESSION["user_id"]=$user_id;
$_SESSION["username"]=$username;
$_SESSION["accesslevel"]=10;
$ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
$proxy = $_SERVER["REMOTE_ADDR"];
$time = time();
header('Location: ../XXXX.php');
In above code I'm trying to establish 2hours of inactivity before session_destroy();. But when i check the cookie information in browser the expiry date is same as creation date.
Help me in extending the cookie time to achieve system idleness.
Image with the cookie inspector (Where it says "Fecha de caducidad" its the Expire date)
How to achieve this, guide me. Thanks in advance!
These settings have no effect after the cookie is created (session initialized)
ini_set("session.cookie_lifetime","7200");
ini_set("session.gc_maxlifetime","7200");
You have to check if session timed out:
if (isset($_SESSION['last_activity']) && (time() - $_SESSION['last_activity'] > $_SESSION['expire_time'] )) {
session_destroy();
} // check last activity
$_SESSION['last_activity'] = time(); // update last activity time
I am creating a website with more than 10 different php files. I want to check if the user is inactive, starting from the login page. So, if a user logs in and remains idle for a specific period of time, it has to log that user out. I am new to PHP and am currently using an answer to similar question which is
if (isset($_SESSION["LAST_ACTIVITY"])) {
if (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
} else if (time() - $_SESSION["LAST_ACTIVITY"] > 60) {
$_SESSION["LAST_ACTIVITY"] = time(); // update last activity time stamp
}
}
I found the answer here:
expire session when there is no activity in PHP
I have created a separate page called session.php and pasted the code in the above link. Then I included the file session.php in my login page (which checks for the credentials entered and logs a user in). The problem is, the if loop is not being run and I do not know how to define $_SESSION['LAST_ACTIVITY'] variable. I used the following in my login page:
$query = "SELECT *
FROM user_details
WHERE username = '$username'
AND password = '$password'";
$result = mysqli_query($dbconnect, $query);
$row = mysqli_fetch_array($result);
$count = mysqli_num_rows($result);
if ($count == 1) {
session_start();
echo "Welcome " .$username. "</br>";
$_SESSION['username'] = $username;
$login_time = time();
$_SESSION["LAST_ACTIVITY"] = $login_time ;
include('session.php');
I also tried including session.php at the beginning of the file but of no use. The problem is: time() - $_SESSION["LAST_ACTIVITY"] is being equalled to 0. How do I store last activity time and compare it with the current time? Also, should I include session.php in every other webpage file for the website to check user activity ? If yes, should I include it at the beginning or at the end ?
This code will solved your problem for session timeout.
<?php
// set timeout period in seconds
$inactive = 60; //after 60 seconds the user gets logged out
// check to see if $_SESSION['timeout'] is set
if(isset($_SESSION['timeout']) ) {
$session_life = time() - $_SESSION['timeout'];
if($session_life > $inactive)
{
session_destroy();
header("Location: Logout.php");
}
}
$_SESSION['timeout'] = time();
?>
Is there any way to set time limitation for session? It means that my application should log out after 1 hour through server settings not like coding level as below.
<?php
if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 7200)) {
// last request was more than 120 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
?>
first, store the last time the user made a request
<?php
session_start();
$_SESSION['LAST_ACTIVITY'] = time();
?>
in subsequent request, check how long ago they made their previous request (30 minutes in this example)
<?php
if (isset($_SESSION['LAST_ACTIVITY']){
if ($_SESSION['LAST_ACTIVITY'] + 30 * 60 < time()) {
// session timed out
session_unset(); // unset $_SESSION variable for the run-time
session_destroy(); // destroy session data in storage
} else {
// session ok
}
}
?>
$timeout = 60*60;//1 hour
session_start();
if (!isset($_SESSION['sessionTime'])) {
$_SESSION['sessionTime'] = time() + $timeout;//first login, set timeout
} else {
if ($_SESSION['sessionTime'] < time()) {//over timeout, destroy session
session_unset();
session_destroy();
} else {
$_SESSION['sessionTime'] = time() + $timeout;//login in timeout, reset timeout
}
}
Cause the question was "not on coding level" => You could achieve this via php.ini and/or .htaccess by setting session.gc_maxlifetime and/or session.cookie_lifetime.
But coding-level is mor reliable and way mor fault-tolerant.
See the best answer of this Question for explanation.
For Detailed Explanation please go through this link : http://php.net/manual/en/function.session-set-cookie-params.php#96868
we can give via session parameters by giving the following command in php
<?php
// Here we start as usual
session_set_cookie_params('3600'); // 1 hour
session_start();
?>
Hope it helps thank you
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
/*
You can also use an additional time stamp to regenerate the session ID periodically to avoid attacks on sessions like session fixation:
*/
if (!isset($_SESSION['CREATED'])) {
$_SESSION['CREATED'] = time();
} else if (time() - $_SESSION['CREATED'] > 1800) {
// session started more than 30 minutes ago
session_regenerate_id(true); // change session ID for the current session an invalidate old session ID
$_SESSION['CREATED'] = time(); // update creation time
}
//note that session.gc_maxlifetime should be at least equal to the life time of this custom expiration handler (1800 in this example).
description here
I have a single form for login for both admin and general users. I would like to time the sessions out after 30 minutes how would I amend my current code to do that?
<?php
session_start(); //Start the session
define(ADMIN,$_SESSION['username']); //Get the user name from the previously registered super global variable
if(!session_is_registered("admin")){ //If session not registered
header("location:../index.php"); // Redirect to login.php page
}
?>
Here is the code to clear the session for a specified time.
To clear the inactive session, you have to renew the session timeout every page.
Hope it helps.
For reference, http://bytes.com/topic/php/insights/889606-setting-timeout-php-sessions
session_start();
$timeout = 60; // Number of seconds until it times out.
// Check if the timeout field exists.
if(isset($_SESSION['timeout'])) {
// See if the number of seconds since the last
// visit is larger than the timeout period.
$duration = time() - (int)$_SESSION['timeout'];
if($duration > $timeout) {
// Destroy the session and restart it.
session_destroy();
session_start();
}
}
// Update the timout field with the current time.
$_SESSION['timeout'] = time();
Via the runtime configuration item session.cookie_lifetime or function session_set_cookie_params()
if ($_SESSION['timeout'] + 30 * 60 < time()) {
// 30 min timeout
}