Session variables are not persisting between page loads - php

Can someone tell me why the session vars are not passing between pages? They were working up to 2 days ago. Now its not? There is a third party system that logs users in based on the third party system. I direct users to the login page with the return url. The third party system logs a user in and passes their id and a token generated on their end and returns them to my site with the id and the token in the url.
If sessions are not set i try and grab the id and the token from the url and set the sessions. (working) I then generate my own token to validate against the token passed from the third party system (working) when i go to click to another page the sessions i set are not empty (????)
Here is my code:
<?php
session_start();
// FUNCTION TO PASS THE URL THE USER IS ON SO THEY COME
// BACk TO THIS PAGE AFTER THE LOG IN. IF APPLICABLE
function curPageURL() {
$pageURL = 'http';
if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
$pageURL .= "://";
if ($_SERVER["SERVER_PORT"] != "80") {
$pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
} else {
$pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
}
return $pageURL;
}
// DESTROY SESSION INFO IF TIMED OUT
if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) {
session_destroy(); // destroy session data in storage
session_unset(); // unset $_SESSION variable for the runtime
}
// SET THE SESSIONS WITH INFO PASSED FROM
// LOGIN PAGE SENT AS A GET
if(isset($_SESSION['ID']) && isset($_SESSION['token'])) {}else{
$_SESSION['ID'] = $_GET['ID'];
$_SESSION['token'] = $_GET['token'];
}
// GENERATE MY TOKEN TO MATCH THE LOGIN SYSTEM TOKEN
$userIP = $_SERVER['REMOTE_ADDR'];
$secretkey = 'A Unique Key For The Logged In User Matching the Login System Passed From mydomain.com/login.php';
$algorithm = 'md5';
$mm = date('m');
$dd = date('d');
$mmdd = $mm.$dd;
$mytoken = strtoupper(hash($algorithm, $secretkey.$_SESSION['ID'].$userIP.$mmdd));
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp
// THIS IS WHERE THINGS ARE GOING WRONG
// SESSION token IS NO LONG SET AFTER I Go To another page
// and my token isnt the same any more either because session ID
// is no longer set???
if($_SESSION['token']==$mytoken){}else{
header("location: https://mydomain.com/login.php?returnURL=".curPageURL());
}
?>
ok this is messed up. It has to be a problem on the hosting providers PHP setup i think because i created two pages. one called info with this code:
<?
session_start();
$_SESSION['ID'] = "112233";
$_SESSION['token'] = "mytoken";
print $_SESSION['ID'];
print $_SESSION['token'];
?>
info 2
and one called info2 with this code:
<?
session_start();
print $_SESSION['ID'];
print $_SESSION['token'];
?>
info
info created and printed the session ok. when i click the link to go to info2 the sessions dont print. Is this a hosting config problem?

As already mentioned, ensure you're calling session_start() on each page.
Additionally, are the scripts on different subdomains?? If they are you should set the INI value session.cookie_domain to .DOMAIN.EXT.
To further debug this whole situation, do some simple cookie watching. See if PHPSESSID is present as a cookie on both page requests, if it's not then this is your problem. You can't store cookies cross-domain unless you reconstruct them.
In response to your update, try doing this underneath your call to session_start():
echo session_id();
Confirm that it's the same on both pages. If not, check the value of session.cookie_domain like this:
echo ini_get('session.cookie_domain');
Is that set to anything? By default it should be blank, if it's set, especially not to your domain, this is the problem.
You can also try debugging the cookie value of PHPSESSID like I first suggested.

Check List
1. Make sure that you have used session_start(); in the next page.
2. Are you using .htaccess file?
if so remove the .htaccess file and check the same.
some time rewrite rules cause session probs...
3. If session is working fine and you have trouble only with token, then check the token sent in url is url_encoded.

it's not the hosting server issue...
check your URLs
if a user is login under "example.com" session will be stored for "example.com" and not "WWW.example.com" so if a link goes to www.example.com it will not have that session.
you can use htaccess to always set the url to "WWW.example.com" use below code for it
RewriteEngine On
RewriteCond %{HTTP_HOST} ^hemantjadhav.com$ [NC]
RewriteRule ^(.*)$ http://www.hemantjadhav.com/$1 [L,R=301]
(replace hemantjadhav with your domain name)

Check the size of the session file: (code taken from this post)
$sessionfile = ini_get('session.save_path') . '/' . 'sess_'.session_id();
echo 'session file: ', $sessionfile, ' ';
echo 'size: ', filesize($sessionfile), "\n";
If your session file has zero size, make sure there is still disk space available on your server. That was the problem I had.
Check disk space with df -h on a linux server.

The answer to this is it was a hosting configuration error. Hosting company changed something and it has worked ever since.

In my case the solution was to have different parameter names in $_GET and $_SESSION.
$_SESSION["businessid"] = $_GET["businessid"]; // Leads to problems with session.
$_SESSION["business_id"] = $_GET["businessid"]; //Works perfectly.
It sounds strange but that's my experience.

The only answer for this problem is to use session_start(); on the top of every page. It will work fine. Else you might need to contact your hosting provider about this problem.

I would add that I got caught up with the same problem, except that in my case page was behind Varnish caching proxy and I missed out that configuration had a line where cookies were allowed only on specific paths, otherwise they would get removed with the following directive:
unset req.http.cookie;
Dont forget to also check your proxy settings.

I had session.cookie_samesite = "Strict" in my runtime file and was trying to bounce my user from Oauth2.0 back to my site and the PHP session ID was getting erased when the redirects hit. I removed this from my runtime file and it works fine now.

For anyone else searching this in frustration - another thing to check is the cookie_secure setting in php.ini.
If cookie_secure=1, cookies will only be sent and persist on secure connections. In our case, the site was deployed to an environment that did not have an ssl setup yet.
Set cookie_secure back to its default (0) - or get the site secured.

Make sure both pages are on the same domain.
Even www.site.com is different than site.com

If the above solutions do not work I suggest you do the following right before you set the new session variables:
session_destroy();
session_start();
and THEN save the new session variables that were not persisting before

In case this helps others:
If sessions are closed (e.g. with session_write_close() or session_commit()), then anything written to a session after that is not persisted.
Re-opening a closed session during the same request seems at best an uncertain endeavor. If anything has been sent back to the client already, session_start() seems to fail (return false) and nothing written to $_SESSION is persisted even if errors are not thrown.
Some may wonder why one would close sessions intentionally in the first place - the reason is "performance". Session resources (e.g. files with file-based sessions) are locked while the session is "open" and so for the duration of handling a request by default unless the session is specifically closed. If a response is taking awhile on the server (e.g. a long-running report query), a user (or multi-threaded UI) cannot complete another session-locking request while one is already in progress - so effectively all the session-based requests stack up sequentially and users are stuck waiting (the opposite of what is wanted with most modern UIs). The best answer, in most of my cases, is to release (close) the session as soon as possible (typically just after is has been read for the first time when handling a request) and keep it open for the duration of the request handling only if one needs to write to the session later (cases which should be minimized for performance of course).

You did not call session_write_close()

Related

PHP session_id never the same on refresh

I am trying to use session_id() on some php pages, but the id changes between every file and it changes everytime i refresh the page. I placed the following script which should increment on ever reload, but it does not.
session_start();
if (!isset($_SESSION['hits'])) $_SESSION['hits'] = 0;
++$_SESSION['hits'];
echo '<p>Session hits: ', $_SESSION['hits'], '</p>';
echo '<p>Refresh the page or click <a href="', $_SERVER['PHP_SELF'],
'">here</a>.';
In my php.ini file, I have cookies turned on as well as set my save_path tp '/tmp'.
In the actual folder, there are session files... so i know it is not a file writing issue. I have also ensured that every file is utf-8 with bom to ensure consistency.
If there are any other solutions you can think of, please help me solve this. It is driving me insane.
Thanks!!!
The 3 possibilities I can think of for your situation are:
How are you calling session_id()? Include that code in your question. If you're calling it with any arguments it will override the session ID to whatever argument you passed.
Are cookies enabled in your browser? The session ID is sent to the browser as a cookie.
Are you calling session_destroy() at any point? This will delete the session data from the server and cause a new session to be started on subsequent pageviews.
That is because you are creating a new session every time you refresh the page. You must enclose your session start statement in a if.
if(session_id() == ''){
session_start();
}

PHP session variables not preserved with ajax

I have a one page website that uses AJAX to load new php files and update the display.
I start my php session on the main page but when I use ajax to update inner html I need those session variables for the new php file being loaded.
This post is similar to this one: PHP Session Variables Not Preserved . But I checked and my php.ini has session.use_cookies = 1
Main Page PHP:
<?php
session_start();
if(isset($_SESSION['views']))
{$_SESSION['views']=$_SESSION['views']+1;}
else
{$_SESSION['views']=1;}
?>
After User Input I use ajax to call a php file and load a subsection of the page:
<?php
if(isset($_SESSION['views']))
{ echo "Views: " . $_SESSION['views'];}
else
{ echo "Views: NOT SET";}
?>
Can someone please tell me what important step I am missing? Thank you.
Update: After adding session_id() call to both the main and sub pages I see that both pages have the same Session_ID. However it still cannot pull the session variable and if i do assign it a value the two same name session variables stay independent of one another.
Answer to the question that this question created: I found that I had to set a static session_save path in my php.ini file. With most paid webhosting services they just have a default container for sessions but it is affected by load balancing. What a releif.
I think you're missing session_start() on the page that Ajax calls.
You need:
<?php
session_start();
if(isset($_SESSION['views']))
{ echo "Views: " . $_SESSION['views'];}
else
{ echo "Views: NOT SET";}
?>
You need to start session session_start() in the other PHP file also, the one you are calling through AJAX.
I ran into what i thought was the same issue when running PHP 7 on IIS Server 2012 today.
I had added:
if(!isset($_SESSION))
{
session_start();
}
to the start of each AJAX file but kept recieving the following PHP Notice:
PHP Notice: A session had already been started - ignoring session_start()
A bit of searching lead me to this thread which pointed me in the right direction to resolving the issues I encountered. Hopefully the following information will assist others encountering the same issue.
After checking the session.save_path value was set, in my case C:\Windows\Temp, I thought it best to check the folder permissions match those of the user account I was running IIS under.
In my case it turned out that the directory I had nominated for session storage (in php.ini) did not have the same user (security permissions) assigned to it as the one which was running the IIS site.
Interestingly sessions worked fine when not using AJAX requests prior to me adding the new user permissions. However AJAX did not pick up the session until I had corrected the permissions issue. Adding the same user account that IIS is running under immediately resolved this issue.
In the case of using a paid web hosting service the default session save path is automatically set like this:
http://php.net/session.save-path
session.save_path = "/tmp/"
You need to place the static path to your root folder there.
You're trying to use existing session data from your application in an ajax call. To do that, change how you're calling session_start like so:
// With ajax calls
if (session_status()==1) {
session_start();
}
When making ajax calls to php scripts that need existing session data, use session_start after session_status.
http://php.net/session_status
Need to initialize the session before you trying to login through ajax call.
session_start();
Initialize on the top of the page from where you start the login ajax call.
So that the SESSIONID will be created and stored the browser cookie. And sent along with request header during the ajax call, if you do the ajax request to the same domain
For the successive ajax calls browser will use the SESSIONID that created and stored initially in browser cookie, unless we clear the browser cookie or do logout (or set another cookie)

php cookie does not work at the first time reading

I am a beginner for PHP and studying to use cookie for login. Would any body please check my code to see what is my problem, or let me how to fix this problem.
When I open the page at the first time, the cookie will not work. It will work when I repeated to open that link. However, I still could not make it work after I use function include and header One of codes is :
One code cookie.php is :
<?php
setcookie("cookiename",$_REQUEST['name']);
if(isset($_COOKIE['cookiename'])){
$cookieSet = ' The Cookie is ' . $_COOKIE['cookiename'];
} else {
$cookieset = ' No Cookie has been set';
}
setcookie("cookiepwd",$_REQUEST['pwd']);
print_r($_COOKIE);
?>
When I run this code first time, it will does not show any thing. I can see cookie data at second time. From some website it is said that cookie would not be read at the same page.
So I moved print_r($_COOKIE) to second php file as well as added function include() or header() to above file, but both neither works.
Cookie2.php:
<?php
setcookie("cookiename",$_REQUEST['name']);
if(isset($_COOKIE['cookiename'])){
$cookieSet = ' The Cookie is ' . $_COOKIE['cookiename'];
} else {
$cookieset = ' No Cookie has been set';
}
setcookie("cookiepwd",$_REQUEST['pwd']);
include(‘printcookie.php’);
//or header("Location: printcookie.php")
?>
printcookie.php:
<?php
print_r($_COOKIE);
?>
Thank you very much for answering in advance!
Michelle
setcookie only sets up the header, that is being sent to the client. It doesn't change the $_COOKIE superglobal.
In other hand - $_COOKIE is filled up with the cookies sent from the client
So at first step - you set the cookie with setcookie and have nothing in $_COOKIE because client hasn't sent it yet, and will only on the next request.
And there is no way of doing what you want, rather than modifying $_COOKIE manually
PS: it is a bad idea to put user's password in the cookie
Give zerkms the answer, but I just want to reiterate:
Cookies are not bad for storing bits of info like the user's theme preferences or preferred start page, etc. They get their bad rep from being used for identity and authentication handling. There are cookies out there that basically have "isAdmin=0" in order to control user access. It is very easy to change that to isAdmin=1 and have a field day. Since you are new to PHP, take the time to learn about sessions now while it's all new to you.
When you set a cookie using setcookie, you are sending an HTTP header to the browser with the cookie info. The browser will then pass back that cookie in any future requests to the server. The $_COOKIE global variable holds the cookie info passed in from the browser to the server.
Since you are using $_REQUEST to get the cookie name, you don't need to check the cookie (otherwise you wouldn't have the data to set it right?). So consider going this route:
if(!isset($_COOKIE['cookiename'])) {
$name = $_POST['name']);
setcookie("cookiename",$name);
} else {
$name = $_COOKIE['cookiename']);
}
echo "Welcome back $name!";
This will also help out if they clear cookies, etc.
But really, the safer route is:
session_start();
if(!isset($_SESSION['name'])){
$_SESSION['name'] = $_POST['name']);
}
if(!isset($_SESSION['pwd'])){
$_SESSION['pwd'] = $_POST['pwd']);
}
$name = $_SESSION['name'];
$pwd = $_SESSION['pwd'];
And even this would be frowned upon for serious web security, where you should simply check the password against a stored hash and then delete it, using other global variables to confirm session integrity. But there's now a whole StackExchange for that.
As a workaround you could use location() after checking the cookie to have access to the stored data.
But be aware that location() fails, if anything (including breaks and blanks in your script) already sent to the browser.

PHP session doesn't work correctly maybe because of fb? please help

I have a question about PHP sessions. I use a session to keep a visitor logged in. I have made a site before with this and works perfect. Now I am making a Facebook app.
When logging in (checking if user is registered in database), I register id. After that I use:
if(session_is_registered("id"))
{
echo "Logged in";
}
So if it shows "Logged in" in the browser, I am absolutely sure that the session is registered. But when I go to the next page (which has session_start(); at the top of the page), there's no session anymore. But if I go to the logout page (with session_destroy();), and then proceed to the login, the session is registered correctly. Also if I close all the browser windows and then go to login, it won't register correctly.
I tried destroying the session right before registering the 'id', but that also doesn't work.
I'm guessing I made a basic error, so someone on here should be able to help me without wasting a lot of time.
Please help me. I have wasted days on this.
Thanks in advance.
More code:
Where session is registered:
$id_query = mysql_query ("
SELECT * FROM Tour11_deelnemers WHERE fb_id = '$user'");
while ($record = mysql_fetch_assoc ($id_query))
{
$id = $record['deelnemer_id'];
}
if($id > 0)
{
$speelid = $id;
session_register("speelid");
}
After that to check if it is registered:
if(session_is_registered("speelid"))
{
echo "Ingelogd";
}
session_is_registered() is same as isset() for $_SESSION.
So the thing I don't understand is while session_is_registered() is true after it is registered, on the next page it is false again :( unless I login immediately after going to logging out page (session_destroy();). So even if i destroy the session just before restarting it and registering again, it doesn't help.
Here is a solution for you.
Set the session like this:
if(!isset($_SESSION['speelid'])){
$id_query = mysql_query ("SELECT * FROM Tour11_deelnemers WHERE fb_id = '$user'");
while ($record = mysql_fetch_assoc ($id_query)){
$id = $record['deelnemer_id'];
}
if($id > 0){
$_SESSION['speelid'] = $id;
}
}
Check if a session is set like this:
if(isset($_SESSION['speelid'])){
echo "Ingelogd";
}
Update
It seems like the issue is related to >= IE6 refusing to accept the session cookie generated by the php, when a .php file is referred from an .html file on a different server.
.HTML to .PHP session IE issue
When using session
variables in a .php file referred by a
frame (.html, or other file type) at a
different server than the one serving
the .php:
Under these conditions IE6 or later
silently refuses the session cookie
that is attempted to create (either
implicitly or explicitly by invoquing
session_start()).
As a consequence, your session
variable will return an empty value.
According to MS kb, the workaround is
to add a header that says your remote
.php page will not abuse from the fact
that permission has been granted.
Place this header on the .php file
that will create/update the session
variables you want:
Here is a full thread on this issue
Solution
The solution is to add this at the very top of the page which will SET the session.
<?php header('P3P: CP="CAO PSA OUR"'); ?>

PHP session HTTP to HTTPS problem

I have a (HTTPS) login.php page which remains HTTPS (ie once user logged in goes to account dashboard). Now the problem is say the user whilst logged on to the secure dashboard clicks onto a non-sensitive page like (HTTP) about-us.php page, the session is not transmitted over HTTP as I have session.cookie_secure=1, meaning the user appears logged out on HTTP pages.
However when the user goes back to dashboard page or any sensitive account page I have been told he should still be logged in (ie from HTTP back to HTTPS)? However this is not the case and he appears logged out on the HTTPS connection too?
I believe I am missing something which is causing this problem. Here is my code:
This is PHP header file which is called to start session on login.php page:
session_start();
session_regenerate_id(true); /*avoid session fixation attempt*/
/*Create and check how long session has been started (over 5 mins) regenerate id - avoid session hijack*/
if(!isset($_SESSION['CREATED']))
{
$_SESSION['CREATED'] = time();/*time created session, ie from login/contact advertiser/email_confirm only ways for new session to start*/
}
elseif(time() - $_SESSION['CREATED'] > 300)
{
/*session started more than 5 mins(300 secs) ago*/
session_regenerate_id(true); /*change session ID for the current session and invalidate old session ID*/
$_SESSION['CREATED'] = time(); /*update creation time*/
}
/*Check if user is logged in*/
if(!isset($_SESSION['loggedin']))
{
$_SESSION['loggedin']=1;/*used to track if user is logged in on pages*/
}
/*if return false browser supports standard ob_start();*/
if(ob_start("ob_gzhandler")){ob_start();}
This is PHP header file required on every page to check if session initiated already:
session_start();
$session_errors=0;/* if>0 user not logged in*/
/*check if session is already initiated*/
if(isset($_SESSION['CREATED']))
{
if(time() - $_SESSION['CREATED'] > 300)
{
/*session started more than 5 mins(300 secs) ago*/
session_regenerate_id(true); /*change session ID for the current session and invalidate old session ID*/
$_SESSION['CREATED'] = time(); /*update creation time*/
}
}
elseif(!isset($_SESSION['CREATED'])){$session_errors++;}/*user not logged in*/
/*Check if user is logged in*/
if(!isset($_SESSION['loggedin'])){$session_errors++;}/*user not logged in*/
if(ob_start("ob_gzhandler")){ob_start();}
Also if any use this is the code to turn HTTPS of on non-sensitive pages such as about-us.php
if ($_SERVER['SERVER_PORT']!=80)
{
$url = "http://". $_SERVER['SERVER_NAME'] . ":80".$_SERVER['REQUEST_URI'];
header("Location: $url");
}
My php.ini file cookie settings
session.cookie_secure=1
session.cookie_httponly=1
session.use_only_cookies=1
session.cookie_lifetime = 0
session.save_path = /tmp
session.save_handler = files
The description by #rickchristie is good, but I think there's a better solution that he doesn't suggest. If you don't always want to use HTTPS (which does make sense sometimes; the about_us page doesn't need to be secure), you can follow the advice on the session_start page and use named sessions to continue a previous session. This is simple to use; just include the session_start calls with
session_name("MySession"); // replace with whatever makes sense
session_start();
on all secure pages.
Answered to help people who might stumble across this
As the the answer at Session lost when switching from HTTP to HTTPS in PHP has concluded, since you are using session.cookie_secure = 1 the cookie that contains the session ID is not transferred when the connection switches from HTTPS to HTTP. At HTTP connection, when you session_start(), PHP creates a new session id, which replaces the previous session id.
The answer also suggests a solution, pass the session id using query string, which is then picked up by the page. This smells of bad of security flaw. Don't forget the reason why we used HTTPS in the first place!
So the solution I suggest to you is that you redirect all http request to https counterparts. Use HTTPS for everything in your site, from css, images, to mundane static html pages. This is actually something that every application that is serious about security does. For example, visiting github page using HTTP will return:
HTTP/1.1 301 Moved Permanently
Server: nginx/0.7.67
Date: Sun, 08 May 2011 15:43:01 GMT
Content-Type: text/html
Content-Length: 185
Connection: close
Location: https://github.com/
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/0.7.67</center>
</body>
</html>
Remember why you used HTTPS in the first place, if you want to be totally secure, use HTTPS for everything.
Detect if the request is HTTPS or not (See this question) at bootstrap.
If the request is HTTP, either redirect all requests to HTTPS home page, or you can try parsing $_SERVER['REQUEST_URI'] and redirecting HTTP request to their HTTPS counterpart using parse_url and http_build_url.
Second Alternative Solution
If you really really don't want to use HTTPS for everything, then don't session_start() on pages that are accessed with HTTP. Secure cookies will be retained when you do this.
Third Alternative Solution
The other solution is to try and detect the user by IP addresses and user agent. This is not guaranteed to be accurate, so what I suggest is just use HTTPS for everything. Paypal, for example, always use HTTPS even for mundane static pages.

Categories