Session lost when switching from HTTP to HTTPS in

2019-01-01 10:46发布

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.

15条回答
无色无味的生活
2楼-- · 2019-01-01 11:10

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.

查看更多
高级女魔头
3楼-- · 2019-01-01 11:11

I had a similar problem, however, this solution was good for me, perhaps will help others in the future

add this in your php.ini

suhosin.session.cryptdocroot = Off

suhosin.cookie.cryptdocroot = Off

查看更多
步步皆殇っ
4楼-- · 2019-01-01 11:13

Do you have a dedicated IP? on some shared environments the https and the http are routed through different servers, so switching actually loses access to the cookies since they're on different domains.

solutions would be: dedicated ip

forcing https on all pages at all times

查看更多
路过你的时光
5楼-- · 2019-01-01 11:15

The following solution assumes the secure and non-secure servers have access to the same backend services (cache, database store, etc).

We had to deal with this same issue when sending a user to our checkout flow when they were done shopping. To solve this, we put in place a caching layer and cached all the pertinent data. For example, we would glean the product ids and user id from the session values, serialize them, create a hash, and finally store the session data within cache using the hash as the key. We would then redirect user to the secure site with the hash in the url.

When the user ended up on the secure site we would attempt to pull the data out of cache based on the hash. Then with the user id and product ids we could load all the pricing and description data out of the database and present to the user for final checkout review.

There is an inherit risk in that the cache data is volatile, but we have never had any issues with it as the redirect happens quickly.

查看更多
情到深处是孤独
6楼-- · 2019-01-01 11:17

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.

查看更多
像晚风撩人
7楼-- · 2019-01-01 11:17

We had this issue as well. It turned out to be because we were using the suhosin patch on our PHP installation. We fix it by setting suhosin.session.cryptdocroot = Off in /etc/php.d/suhosin.ini.

For the suhosin manual about suhosin.session.cryptdocroot see http://www.hardened-php.net/suhosin/configuration.html#suhosin.session.cryptdocroot.

We originally found the fix from this blog post: http://www.yireo.com/blog/general-news/315-switch-between-http-and-https-looses-php-session.

查看更多
登录 后发表回答