PHP Session expiration - works stand alone but not in a function - php

when I issue this code from a function, the cookies expire at the end of the session
$validuntil = '2024-02-17';
$validuntil = strtotime ($validuntil);
setcookie ('vid',$vid,$validuntil,'/');
setcookie ('pwd',$pwd,$validuntil,'/');
However, executing the exact same code in a stand alone php file sets the cookies to expire on the correct date.
Here is the function
function validuser ($vid, $pwd){
global $pdo;
$stmnt = $pdo->prepare ("select * from members where vid = :vid and password = :password");
$stmnt->bindParam (':vid',$vid);
$stmnt->bindParam (':password', $pwd);
$stmnt->execute();
if ( $stmnt->rowCount() != 1){
header("Location:invalid.php");
break;
}
$member = $stmnt->fetch (PDO::FETCH_OBJ);
if ($member->nickname!="")
$_SESSION['user']= $member->nickname." ".$member->lname;
else
$_SESSION['user']= $member->fname." ".$member->lname;
$validuntil = '2024-02-17';
$validuntil = strtotime ($validuntil);
setcookie ('vid',$vid,$validuntil,'/');
setcookie ('pwd',$pwd,$validuntil,'/');
$_SESSION['ulot'] = $member->ulot;
$_SESSION['valid'] = '101150';
$_SESSION['admin'] = $member->admin == 1;
$_SESSION['vid'] = $member->vid;
$_SESSION['resid'] = $member->vid;
$_SESSION['pwd'] = $member->pwd;
$_SESSION['user'] = $member->fname." ".$member->lname;
header ("Location:mainmenu.php");
}
Can someone please explain this and how I fix it.
Thanks,

Related

Why I can't set cookie?

I'm coding a basic website and I want to set a cookie named 'color' at the beginning of the session.
For that mean, I used this code :
<?php
require_once("../model/connection.php");
if (!(empty($_POST['user_email'])) and !(empty($_POST['user_password']))){
$login = $_POST['user_email'];
$password = $_POST['user_password'];
$stmt = $conn->prepare('SELECT ID, color FROM Player WHERE mail = ? AND password = ?');
$stmt->bind_param('ss',$login,$password);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
session_start();
$row = $stmt->fetch_assoc();
$_SESSION['ID'] = $row['ID'];
setcookie("color", $row['color'], time() + 365*24*3600) or die('unable to create cookie');
header("Location: ../view/index.php");
}
}
else {
header("Location: ../view/index.php?error=false");
}
But when I call var_dump('$_COOKIE['color'], php returns
Notice: Undefined index: color in /Applications/MAMP/htdocs/controller/controller_game.php on line 7
There is certainly a basic thing I don't understand, sorry I'm a beginner.
By the way, my request is good, I tested it.
Thanks for your time.
Add the last parameter / and it should work. As follows
setcookie("color", $row['color'], time() + 365*24*3600, "/");
Hope this helps

How to expire a php session after certain time? [duplicate]

This question already has answers here:
How do I expire a PHP session after 30 minutes?
(17 answers)
Closed 5 years ago.
I have the following code:
The page Login.php
<?PHP
session_start();
include("conexion.php");
$conn = conexion();
extract($_POST);
$password = md5($pass);
echo $password;
$sql1="Select * from miembro where user='".$user."'and pass ='".$password."'";
$re= mysqli_query($conn,$sql1);
$numrows1 = mysqli_num_rows($re);
echo $sql1;
echo $numrows1;
if ($numrows1==0 or $numrows1>=2){
$_SESSION['session'] = "no";
header('Location:' . getenv('HTTP_REFERER'));
}else{
$row = mysqli_fetch_array($re);
$_SESSION['nombre'] = $row["nombre"];
echo $_SESSION['nombre'];
$_SESSION['codigo'] = $row["codigo"];
$_SESSION['pass'] = $row["pass"];
$_SESSION['apellido'] = $row["apellido"];
$_SESSION['telefono'] = $row["telefono"];
$_SESSION['user'] = $row["user"];
$_SESSION['cargo'] = $row["cargo"];
$_SESSION['correo'] = $row["correo"];
$_SESSION['session'] = "si";
$_SESSION['last_time'] = time();
header("Location: ./actions/perfil.php");
}
?>
And perfil.php (where the user is taken once logged in)
<?php
include("./menu_actions.php");
include("../conexion.php");
if($_SESSION['session'] != "si"){
header("location: ../home.php");
}
$us = $_SESSION['user'];
$sql="select * from miembro where user = '$us';";
echo $sql;
$query = mysqli_query(conexion(),$sql);
$row = mysqli_fetch_array($query);
session_start();
if(isset($_SESSION["user"])){
if((time() - $_SESSION['last_time']) > 10){ //After 10 sec
header("location:logout.php");
}
}
else{
header('Location:login.php');
}
?>
//HTML
It's not working and I don't understand why. The time of the start of the session is kept in a variable and analyzed later with an if loop, so if the time exceeds 10 seconds, the user should be forced out and taken to the login page again, but I can't make it work. Could somebody help me, please?
Hmm, maybe try to set cookie in this way:
setcookie($cookie_name, $cookie_value, time() + 10, "/"); // 86400 is one day
then check is it set instead by isset($_COOKIE[$cookie_name])

why the PHP session is destroyed when page is loading multiple time?

I have website where I am using login and logout functionality using php.
So, for login, first I call following function :
function sec_session_start() {
$session_name = 'happiechef_session_ids'; // Set a custom session name
$secure = false;
// This stops JavaScript being able to access the session id.
$httponly = true;
// Forces sessions to only use cookies.
if (ini_set('session.use_only_cookies', 1) === FALSE) {
header("Location:index");
exit();
}
// Gets current cookies params.
$cookieParams = session_get_cookie_params();
session_set_cookie_params($cookieParams["lifetime"],
$cookieParams["path"],
$cookieParams["domain"],
$secure,
$httponly);
// Sets the session name to the one set above.
session_name($session_name);
session_start(); // Start the PHP session
session_regenerate_id(true); // regenerated the session, delete the old one.
}
and then I call following function to check user login information from mysql database :
function admin_login($email, $pass) {
global $conn;
$query = mysqli_query($conn, "SELECT a_email, a_pass, a_id FROM admin_profile WHERE a_email = '$email' LIMIT 1");
$query_result = mysqli_fetch_array($query);
$a_id = (int) $query_result['a_id'];
$db_hash = htmlspecialchars($query_result['a_pass']);
$num = mysqli_num_rows($query);
if($num == 1) {
if (checkbrute($email) == true) {
// if true account is locked
return false;
} else {
if(verify($pass, $db_hash)) {
$a_id = preg_replace("/[^0-9]+/", "", $a_id);
$email = validate_data($email);
$user_browser = $_SERVER['HTTP_USER_AGENT'];
$_SESSION['logged_admin_user'] = $email;
$_SESSION['logged_admin_id'] = $a_id;
$_SESSION['login_string'] = hash('sha512', $db_hash . $user_browser);
return true;
} else {
$time = time();
$query = mysqli_query($conn, "INSERT INTO login_attempt VALUES('', '$email', '$time')");
return false;
}
}
} else {
return false;
}
}
Well, when I refresh the page multiple time using F5 key from Keyboard it's automatically logged out and sometime when I visit other page it's asking me to login! Somehow it's destroyed the PHP session.
Can anyone tell me what is the problem in my code ?
Thanks In advance.
Update :
Here is the function to check if user is logged or not :
function admin_login_check() {
// Check if all session variables are set
if (isset($_SESSION['logged_admin_user'], $_SESSION['logged_admin_id'], $_SESSION['login_string'])) {
global $conn;
$user_id = $_SESSION['logged_admin_id'];
$login_string = $_SESSION['login_string'];
$username = $_SESSION['logged_admin_user'];
// Get the user-agent string of the user.
$user_browser = $_SERVER['HTTP_USER_AGENT'];
if($query = mysqli_query($conn, "SELECT a_pass FROM admin_profile WHERE a_email = '$username' ")) {
$num = mysqli_num_rows($query);
if($num == 1) {
$result = mysqli_fetch_array($query);
$password = htmlspecialchars($result['a_pass']);
// if hash equals function is not exist
if(!function_exists('hash_equals')){
function hash_equals($str1, $str2){
if(strlen($str1) != strlen($str2)){
return false;
} else {
$res = $str1 ^ $str2;
$ret = 0;
for($i = strlen($res) - 1; $i >= 0; $i--) {
$ret |= ord($res[$i]);
}
return !$ret;
}
}
}
$login_check = hash('sha512', $password.$user_browser);
if (hash_equals($login_check, $login_string) ){
return true;
} else {
return false;
}
} else {
return false;
}
} else {
return false;
}
} else {
return false;
}
}
If you remove the session_regenerate_id(true) the session should not destroyed anymore.
Why is this happening?
session_regenerate_id() replace the current session ID with a new one. The session information will be kept. When you use this function to often (reload, AJAX, etc.) you can see this effect on your session. PHP has a restriction for access to the session for only one running task. If you run session_regenerate_id() to often / fast the task get into queue. So the following is happening:
The first call changes the session ID and delete the old session (if parameter is true).
The second call has still the old session ID and tries to do some operations on it.
As the old session doesn't exists anymore, a new session would be created. The user is logged out now (session is invalid now).

Last online php

I am using a simple script at the top of every page that will update a LastActive column in the database:
$username = $_SESSION['username'];
$userID = $_SESSION['user_id'];
if(isset($username, $userID)) {
if ($insert_stmt = $mysqli->prepare("UPDATE Users SET lastActive = DATE_ADD(Now(), interval 6 hour) WHERE username = ?")) {
$insert_stmt->bind_param('s', $username);
// Execute the prepared query.
if (! $insert_stmt->execute()) {
$insert_stmt->close();
header('Location: ../headers/error.php?err=Failed Upload');
}
}
$insert_stmt->close();
}
I always want to keep performance and security in mind. Would this lead to poor performance in the future with 000's of connections?
How does using cookies (not that I know how) differ from a simple script like this?
Thanks
edit:
$username = $_SESSION['username'];
$userID = $_SESSION['user_id'];
$loginTime = $_SESSION['timestamp'];
date_default_timezone_set("Europe/London");
$now = new DateTime();
$diff=$now->diff($loginTime);
$minutes = $diff->format(%i);
if(isset($username, $userID) && $minutes> 30) {
$_SESSION['timestamp'] = $now;
$online = true;
}
Couple of suggestions:
You could do this via AJAX, so that the LastVisited is updated asynchronously after the user's page loads. That way, there won't be any impact to the page load time for the user.
If, for any reason, your SQL query fails, you should fail silently. Since recording Last Visited is not business critical, you should not redirect the user to an error page. Maybe just log an error, and set up an alert so if there are multiple failures, you get alerted and can take a look at it.
All that you made with cookies will be data supplied by your users, then you cannot trust it.
In other hand, if you work with cookies, all of them will travel in each request header.
You should do it in server side and yes, a database is not performant.
You can try to persist this information with something like Redis, a in-memory data structure store, used as database, cache and message broker.
I thought I'd post the way I got around this for any one else looking for a User Online type method. Of course this might have been done much better but works in my situation.
I am using both database entries and session to test if a user is online.
On user login I update a column in my users table with a Now() timestamp and add this to their session data.
At the top of each page I am running a script to check if the user is logged in and get their timestamp from session data. if this data is 45 minutes old, the script will update the table setting the lastActive column of my users table to Now();
<?php
include_once 'functions.php';
if(isset($_SESSION['username'], $_SESSION['user_id'], $_SESSION['lastActive'])) {
date_default_timezone_set("Europe/London");
$now = new DateTime();
$lastActive = $_SESSION['lastActive'];
$diff=$now->diff($lastActive);
$hours = $diff->format('%h');
$mins = $diff->format('%i');
$day = $diff->format('%d');
$month = $diff->format('%m');
$year = $diff->format('%y');
if($mins > 45 || $hours >= 1 || $day >= 1 || $month >= 1 || $year >= 1) {
$_SESSION['lastActive'] = $now;
set_last_active($mysqli, $_SESSION['username']);
}
}
set_latst_action is simply just:
function set_last_active($mysqli, $username) {
if ($stmt = $mysqli->prepare("UPDATE Users SET lastActive = Now() WHERE username = ?")) {
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->close();
}
}
then when I want to see if a user is online for example on a profile page I call isOnline();
function isOnline($mysqli, $username) {
if ($stmt = $mysqli->prepare("SELECT lastActive FROM Users WHERE username = ? LIMIT 1")) {
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
$stmt->bind_result($return);
$stmt->fetch();
$lastActive = $return;
} else {
// user does not exist
$lastActive = "";
return $lastActive;
$stmt->close();
}
} else {
// SELECT failed
$lastActive = "";
return $lastActive;
$stmt->close();
}
if (!empty($lastActive)) {
date_default_timezone_set("Europe/London");
$dateNow = new DateTime;
$lastActiveDate = new DateTime($lastActive);
$diff=$dateNow->diff($lastActiveDate);
$hours = $diff->format('%h');
$mins = $diff->format('%i');
$day = $diff->format('%d');
$month = $diff->format('%m');
$year = $diff->format('%y');
if ($mins > 45 || $hours >= 1 || $days >= 1 || $month >= 1 || $year >= 1) {
$return = "Offline";
return $return;
}
else {
$return = "Online";
return $return;
}
}
else {
$return = "Offline";
return $return;
}
}

Session lost after page redirect in php

When I use php header redirection all session variables are lost... Some people say that adding exit(); just after the header(""); will solve the problem but it doesn't seem to be the solution...
Can anyone please help?
Here is how I store variable into the session:
include 'dbc.php';
$err = array();
foreach($_GET as $key => $value) {
$get[$key] = filter($value); //get variables are filtered.
}
if ($_POST['doLogin']=='Login')
{
foreach($_POST as $key => $value) {
$data[$key] = filter($value); // post variables are filtered
}
$user_email = $data['usr_email'];
$pass = $data['pwd'];
if (strpos($user_email,'#') === false) {
$user_cond = "user_name='$user_email'";
} else {
$user_cond = "user_email='$user_email'";
}
$result = mysql_query("SELECT `id`,`pwd`,`full_name`,`approved`,`user_level` FROM users WHERE
$user_cond
AND `banned` = '0'
") or die (mysql_error());
$num = mysql_num_rows($result);
// Match row found with more than 1 results - the user is authenticated.
if ( $num > 0 ) {
list($id,$pwd,$full_name,$approved,$user_level) = mysql_fetch_row($result);
if(!$approved) {
//$msg = urlencode("Account not activated. Please check your email for activation code");
$err[] = "Account not activated. Please check your email for activation code";
//header("Location: login.php?msg=$msg");
//exit();
}
//check against salt
if ($pwd === PwdHash($pass,substr($pwd,0,9))) {
// this sets session and logs user in
session_start();
session_regenerate_id (true); //prevent against session fixation attacks.
// this sets variables in the session
$_SESSION['user_id']= $id;
$_SESSION['user_name'] = $full_name;
$_SESSION['user_level'] = $user_level;
$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
//update the timestamp and key for cookie
$stamp = time();
$ckey = GenKey();
mysql_query("update users set `ctime`='$stamp', `ckey` = '$ckey' where id='$id'") or die(mysql_error());
//set a cookie
if(isset($_POST['remember'])){
setcookie("user_id", $_SESSION['user_id'], time()+60*60*24*COOKIE_TIME_OUT, "/");
setcookie("user_key", sha1($ckey), time()+60*60*24*COOKIE_TIME_OUT, "/");
setcookie("user_name",$_SESSION['user_name'], time()+60*60*24*COOKIE_TIME_OUT, "/");
}
if(empty($err)){
header("Location: myaccount.php");
}
}
else
{
//$msg = urlencode("Invalid Login. Please try again with correct user email and password. ");
$err[] = "Invalid Login. Please try again with correct user email and password.";
//header("Location: login.php?msg=$msg");
}
} else {
$err[] = "Error - Invalid login. No such user exists";
}
}
Redirection code:
//connect database
require_once 'dbc.php';
page_protect();
$authorID = $_SESSION['user_id'];
if ( !empty($_POST["answ_content"]) && $authorID != 0 ) {
//vaqciot html chveulebriv texad
$content = htmlentities($_POST["answ_content"],ENT_COMPAT,'UTF-8');
$dro = date('Y-m-d H:i:s');
$qID = $_POST["question_ID"];
$author = $_SESSION["user_name"];
$sql="INSERT INTO wp_comments (comment_ID, comment_post_ID, comment_author, comment_author_IP, comment_date, comment_content, user_id)
VALUES
(NULL, '$qID', '$author', '123.123.123.123', '$dro', '$content', '$authorID')";
$result = mysql_query($sql);
//pasuxebis raodenobis ertit gazrda
$increase = "UPDATE wp_posts SET comment_count = comment_count+1 WHERE ID = $qID";
mysql_query($increase);
//gadamisamarteba shekitxvis gverdze
$url = 'Location:http://example.com/site/answ/question.php?ID=' .$qID;
header($url);
} else {
echo 'error';
}
You need to put exit(); after your header redirection, otherwise you have just loaded two pages of content into 1 page.
Also make sure you have session_start(); at the top of all your scripts.
You aren't starting the session. In order to use session variables and have them carry across pages, you need to put
session_start();
at the top of each page before anything else.
I was trying to set the session id of my own using :
session_id('own_generated_session_id_string');
But as the documentation says, you have to use this before
session_start();
Using it after session_start(), clears the session parameters.
Simples! make sure the page you are coming from (e.g. www.example.com) redirects to a (eg.g www.example.com/redirect.php) notice www at the beginning. If you change that from page to page, then yes things get wonky.
These sessions does not always work as we expect sometimes. I had a similar problem with my website using sessions that get lost. I basically solved it by injecting the value I want to keep on the session into the hidden text field the first time the page loads. Then the second time I call the page(page submit) I simply read the value from the hidden text field and carry on with rest of my code.
That's more easier and cleaner than using sessions in this case!
exit; should be placed after header redirection or session_regenerate_id(true); can be used
You just need to check the file permission in /var/lib/php directory
give yje public permisssion to /var/lib/php/session directory.
and all done.
Include session_start(); in both the files before the session.
Note don't use session_destroy() in the redirected file.

Categories