Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Session lost when switching from HTTP to HTTPS in PHP

When sending the user to a checkout page, they are switched from http://sitename.com to https://sitename.com.

As a result, $_SESSION variables are lost.

The site has a valid SSL certificate which may or may not be of some use.

like image 685
Allan Avatar asked Jan 14 '09 00:01

Allan


People also ask

How long does PHP retain session variables by default?

By default, session variables last until the user closes the browser. So; Session variables hold information about one single user, and are available to all pages in one application. Tip: If you need a permanent storage, you may want to store the data in a database.

How does PHP keep track of sessions?

The session functions keep track of users by issuing them cookies with a randomly generated session IDs. If PHP detects that a user doesn't accept the session ID cookie, it automatically adds the session ID to URLs and forms.

How PHP session is created and destroyed?

A PHP session can be destroyed by session_destroy() function. This function does not need any argument and a single call can destroy all the session variables. If you want to destroy a single session variable then you can use unset() function to unset a session variable.

What is default timeout of PHP session?

1440 seconds is the default which is actually 24 minutes.


2 Answers

When you switch between the HTTP and HTTPS services on the same server, your HTTP session ID is not being passed to the HTTPS session. You can set it by passing the session ID from the HTTP page to the HTTPS page in one of three possible ways:

From PHP: session_start:

session_start() creates a session or resumes the current one based on the current session id that's being passed via a request, such as GET, POST, or a cookie

When you are using sessions, you will normally start your script with session_start(). If the browser has a session ID cookie set, session_start() will use that session ID. If the browser does not have a session ID cookie set, session_start() will create a new one.

If the session ID is not set(in your example, the browser is creating a new session ID cookie for the HTTPS session), you can set it using the session_id() function. session_id() also conveniently returns the session ID as a string. So

...  $currentSessionID = session_id();  ... 

sets the $currentSessionID variable equal to the current session ID, and

...  session_id($aSessionID);  ... 

sets the sessionID cookie in the browser to $aSessionID. from PHP: session_id

Here's an example with two scripts. One is accessed via HTTP and the other is accessed via HTTPS. They must be on the same server to maintain session data.

Script 1(HTTP):

<?php  // This script will create a session and display a link to your secure server address // to transfer your session ID. In this example, the secure page to receive the session // ID is located at http://www.yoursite.com/safePages/securePage.php  // Start a session using the current session ID stored in a cookie, or create // a new session if none is set. session_start();  $currentSessionID = session_id();  // Set a variable that will be retrieved with the HTTPS script. $_SESSION['testvariable'] = 'It worked';  // $secureServerDomain is the domain of your secure server $secureServerDomain = 'www.yoursite.com';  // $securePagePath is the path to the page that will receive and set the session ID. $securePagePath = '/safePages/securePage.php'  echo '<a href="https://' . $secureServerDomain . $securePagePath . '?session="' . $currentSessionID . '">Click here to transfer your session to the secure server</a>';  ?> 

Script 2(HTTPS):

<?php  // Retrieve the session ID as passed via the GET method. $currentSessionID = $_GET['session'];  // Set a cookie for the session ID. session_id($currentSessionID);  // Start a session. session_start();  // Test retrieval of variable set when using HTTP. if (!empty($_SESSION['testvariable'])) {       echo $_SESSION['testvariable']; } else {       echo 'It did not work.'; }  ?> 

For this to work the HTTP and HTTPS servers must use the same session data storage substrate (i.e. for the default files handler, run on the same physical machine with the same php.ini). There are some security flaws here, so I would not use this code to transfer sensitive information. It is just meant as a workable example.

When I ran into this problem before, I came up with the above as a quick fix, but I just remembered the original cause of the problem. I was going from http://www.example.com/page.php to https://example.com/page.php (notice the lack of "www"). Make sure that http://www.example.com/page.php will link to https://www.example.com/page.php and http://example.com will link to https://example.com/page.php.

PS, I didn't actually run these scripts so there may be a typo or two that prevents them from running properly as is.

like image 144
Jacob Avatar answered Sep 22 '22 01:09

Jacob


Sounds like the session cookie is set to be secure. Cookies have a "secure" flag which, if set to true, means that the cookie won't be sent to non-https sites. PHP is probably using that for its session cookies. You can change this with the session_set_cookie_params function, or with the session.cookie_secure setting in php.ini.

like image 37
JW. Avatar answered Sep 19 '22 01:09

JW.