Forum Moderators: coopster

Message Too Old, No Replies

Setting up a PHP session; a new life

New session starts on every page access

         

dstiles

7:00 pm on Dec 18, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Software: latest Apache and PHP on local Manjaro server.
Web browsers: Waterfox and Basilisk.

Trying my hand at converting a few of my sites to linux apache/php after 20-odd years of programming in (expletives) ASP.

First site is fine - just a small, basic one but it works. So I began work on a control panel for it to manage MySql (actually MariaDB), a "copy" of a control panel I designed in ASP years ago.

Much easier to build than in Classic ASP but I cannot get the sessions to stick. The initial problem was discovering that save_path() does not know about full absolute paths. I eventually set up a tmp session folder in the web directory's root and that now works.

Having got that sorted I have another problem. Every time I reload the login page it starts a new session. And if I load the page anew using the browser's URL bar (instead of the reload button) it opens a new tab. I've read at least a couple of hundred forums and manual pages over the past week for this and the save_path() problem and am still puzzled.

My basic starting code at the start of the site's page, before anything else, is:

session_save_path('/srv/tmp/php_session');
ini_set('session.gc_probablilty',1);
session_start();

One of the debugging suggestions I got from the PHP site's manual is...

if($_GET){
//defining the session_id() before session_start() is the secret
session_id($_GET['session_id']);
session_start();
echo "Data: " . $_SESSION['theVar'];
//use your data before below commands
session_destroy();
session_commit();
}else{
//common session statement goes here
session_start();
$session_id=session_id();
$_SESSION['theVar'] = "theData";
echo "your.php?session_id=" . $session_id;
}

This was, accoring to the writer, guaranteed to work. It gives me...

1. On first access of page...
your.php?session_id=(session id)
session variable TheVar=TheData
...suggesting the ELSE clause above was run. A new tab was opened in order to display that. The page itself shows (correctly) a two-field (POST) form for Username and Password. There is no GET to trigger the first clause. I would have expected a GET given it's a primary condition of the protocol (GET logon.php).

2. Entering these I get...
your.php?session_id=(a different session id)
session variable TheVar=TheData
...which shows it took the same clause again. The page opens in another new tab. Form vars are submitted but still no querystring

3. Clicking the reload button I get the same as 2 but a different ID yet again.

4. Pressing Enter in the URL field of the browser gets me the same as 1 with yet another ID.

5. The successful form submission (2) shows a Log Off / End Session button. On clicking this I get a Form field from the button's Submission and a querystring from the button's Action (as designed). I get no session ID and no session variables, as expected (session vars are individually unset but I've also tried session_destroy()).

I've tried garbage collection and session_destroy (which work) but no further in.

The form itself, if relevant, is (leaving out divs, class etc)...

<form name="logonForm" action="/logon.php" method="POST">
Username: <input type="text" name="uid" value="" size="15" maxlength="30">
Password: <input type="password" name="pxman" value="" size="15" maxlength="30">
<input type="Submit" name="Logon" value="Logon">

Any help appreciated. It will save me going somewhat mental. :(

robzilla

8:37 pm on Dec 18, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Are you seeing the session files appear in /srv/tmp/php_session? If not, does the web server have permission to write to that folder?

dstiles

11:44 am on Dec 19, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Session files are being written to the folder and look reasonable. with all the data I expect.

dstiles

10:45 am on Dec 21, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



No one? :(

I'm thinking that session cookies may be necessary? Does anyone have a bit of sample code to help with this problem, please?

Steven29

10:58 am on Dec 21, 2018 (gmt 0)



I havent used session cookies much or in a while but i believe its stored in the session cookie, not the get variable or anything. You should only need to send session_start () and then use the $_SESSION ['variable'] to retrieve your information


session_start();
echo 'the session id is '. $_SESSION ['id'];
$_SESSION ['id']=time();

robzilla

11:10 am on Dec 21, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



A session cookie should be sent to the client by the web server when you first initialize the session with session_start(). Is that happening?

You can use your browser's Developer Tools to check if the cookie is sent, and with what variables (expiration date, etc).

Steven29

11:31 am on Dec 21, 2018 (gmt 0)



Yes, please make sure the cookie headers are being sent correctly. But, the session cookie shouldn't send any variables. It should only send the id of the session that can be looked up in the temporary directory to find the variables attached to that session.

dstiles

3:32 pm on Dec 21, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



> browser's Developer Tools to check if the cookie is sent

Not sure if it's actually sent but no cookies in either browser, even with third party enabled. I suspect they are not being sent.

Session as saved is...

PwxqWe|s:60:"$2y$10$iI7LWmugQx2eJ2MLjyb4I.MVsf0vqA1Nd16Sqy8ET495O4g6J.Kki";PwxqMe|s:12:"aboutbristol";PwxqRf|s:0:"";PwxqNm|s:0:"";pwxqLoggedOn|b:1;Pwxq|s:12:"aboutbristol";

robzilla

7:32 pm on Dec 21, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



You can check the response headers of the page request in the Network tab to see if there's a Set-Cookie header.

If the client doesn't get the cookie, store it and use it for subsequent requests, the next request's always going to be a fresh session.

Maybe also check the [Session] part of your php.ini file to see if, for example, session.use_cookies is set to 1 (default setting, but you never know).

dstiles

2:01 pm on Dec 22, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Thanks for your suggestion.

There is no set-cookie response header in the browser. This seems to indicate cookies are not being pushed by the site.

session.use_cookies and session.use_only_cookies are both 1.

session.cookie_path = /
What should it be, a known folder as with the session itself? Could this be a problem?

session.cookie_only is currently empty but when https is used later on it will be set.

session.use_strict_mode = 1
Can that affect the outcome? I set it to 0 but no difference.

I have already set up HTTPS security headers and tried with and without them.

I have an expiry time of 0 (some time in 1981) which I have changed to 1440 and will look more closely at. Could this have affected the cookies? It done;t seem to on IIS.

Likewise this header has a keepalive timeout 5, max 100 PLUS a Connection: Keep-Alive. Not sure where those came from nor if they are relevant.

Full header at the moment, with Security ones turned off...

Cache-Control: public, must-revalidate, max-age=86400,no-transform
Connection: Keep-Alive
Content-Length: 1640
Content-Type: text/html; charset=UTF-8
Date: Sat, 22 Dec 2018 13:55:41 GMT
Expect-CT: enforce,max-age=30
Expires: 1440
Keep-Alive: timeout=5, max=100
Pragma: no-cache
Server: Apache
200 OK

robzilla

2:32 pm on Dec 22, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Those settings look fine, and those headers aren't really relevant for the session cookie.

Strange that the Set-Cookie header isn't sent even though the session files are created.

Anything in your error log? Are you calling session_start() before the script produces any output? If you have, say, an echo() or some HTML or whitespace before session_start(), that will prevent the headers from being sent because they have to go out first.

dstiles

7:14 pm on Dec 22, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The start of every page is contained in a "globals" file as...

<?php
$path=session_save_path('/srv/tmp/php_session');
// if querystring is as follows kill the session...
if (isset($_REQUEST['uamoz']) && $_REQUEST['uamoz']=='abort') {
ini_set('session.gc_max_lifetime', 0);
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 1);
session_start();
session_gc();
session_destroy();
}
ini_set('session.gc_max_lifetime', 1000);
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 100);
session_start();
....

There was an echo for tracing at the start of the IF clause but presumably the destroy and subsequent start overcame it. In any case, I've now removed it.

Before I read your latest post and, hence, before removing the above echo I tracked down a variable that does not appear anywhere above or in the headers. In httpd.conf I found...

header set Set-Cookie HttpOnly:Secure

As mentioned, my intention has been to ultimately turn the site into HTTPS but am developing it as HTTP. I had already set up all the security headers in httpd.conf and htaccess (taken from a setup I have for a webmail server elsewhere) and had temporarily removed the htaccess ones. The above cookie setting is in the conf file. I commented it out and Behold! It remembers the session!

Except... there is still no mention of setting a cookie in the page header. Curious?

I have re-enabled everything except the set-cookie and it still works. Since the cookie needs to be set in the conf file I assume apache processes it in some way. Whether or not this will work correctly when I set it to HTTPS is to be discovered. I intend setting up another site first, then applying letsencrypt to them both. Haven't had any success with letsencrypt on IIS nor the mail server so I've put it off for the moment.

robzilla

8:30 pm on Dec 22, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



header set Set-Cookie HttpOnly:Secure

So you're running an Apache version lower than 2.2.4?

That colon should be a semi-colon, but I'm not sure exactly how this works in Apache. It does seem likely that Apache was overruling the Set-Cookie header from PHP. Note that there's a session.cookie_httponly setting in php.ini that achieves the same thing as what that custom header is presumably attempting to do.

Still, if the session sticks, you would expect the cookie to exist locally. Did you check the Cookies view in the Developer Tools? In Chrome, it's under Application > Storage.

Another thing that may be relevant is here is that you're working with localhost. See this post [php.net].

dstiles

2:23 pm on Dec 23, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Version 2.4.37 built October this year. My mail server one is apache2 version 2.4.18 built June this year.

Sorry, it's a semi-colon. I copied it by sight from another machine.

session.cookie_httponly is present but not set.

In firefox-type browsers cookies are under Privacy section. Yes, the cookie is now present with correct info and "Send for any type connection" and "expires at end of session".

I'm not actually using setcookie (but assume it is called anyway?) but I read it anyway. I'm using a local domain instead of localhost but it doesn't have dots in it. Still, seems to be working...

Many thanks for your help in this. robzilla. Much appreciated.

robzilla

4:20 pm on Dec 23, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Great! :-) Happy holidays.

dstiles

10:57 am on Dec 24, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



And to you - and to all hereabouts! :)