H3XED

Magento HTTPS Redirect Loop with Cloudflare Flexible SSL

Please note that this post is over a year old and may contain outdated information.
If your Magento store uses CloudFlare's free Flexible SSL to encrypt the visitor-to-CloudFlare connection, you may run into a redirect loop problem on any Magento page that forces https, such as log in, account, and checkout. You may also run into an issue where Magento serves http assets on https pages, causing the browser to block them.

Server Variable
These problems are likely caused by the server variables not reflecting https. The specific server variable that Magento looks for is called HTTPS (upper-case) and it must be set to on (lower-case) when on an https page, or else Magento may enter a redirect loop. The reason it is not being set is because of how CloudFlare's Flexible SSL works.

How Flexible SSL Works
With CloudFlare Flexible SSL, the connection is encrypted from the visitor to CloudFlare (https), and unencrypted from CloudFlare to your server (http).

CloudFlare Flexible SSL Diagram

What happens is that the server thinks the connection is over http, and sets the server variables accordingly. It is doing the right thing, since the connection from CloudFlare to the server is indeed over http, despite the visitor-to-CloudFlare connection being over https.

When the Magento store gets the request to an https-only page, it sees port 80 with protocol http, and not port 443 with protocol https, so it redirects the user to https. Since the visitor is already on https, the redirect loop continues endlessly.

How to Fix It
CloudFlare injects some server variables that can be used to determine if the visitor-to-CloudFlare connection was made over https. You need to edit Magento so that it looks for these variables, and if they exist and are set to their https values, set HTTPS to on.

One way to do this is to create a small PHP patch file and include it into your Magento store. Here is PHP code that will do the trick:

foreach (array(
    'SERVER_PORT' => 443,
    'HTTP_X_FORWARDED_PROTO' => 'https',
    'HTTP_CF_VISITOR' => '{"scheme":"https"}'
) as $key => $value) {
    if (isset($_SERVER[$key]) && $_SERVER[$key] == $value) {
        $_SERVER['HTTPS'] = 'on';
        break;
    }
}

What this does is check each of three possible server variables to see if they exist and are set to their respective https values. It does this without polluting the namespace of Magento, which is why the array declaration is inside the foreach loop.
Share This Post
Twitter
Learning Magento
Magento Beginner's Guide
Magento Beginner's Guide
See More Details
Magento SEO
Magento SEO
See More Details

Comments (8)

Rafael Ribeiro   Feb 28, 2016
Internal Server Error 500
Khushi Bhardwaj   Jan 12, 2016
thank you much for this post!!
Anaz Haidhar   Oct 11, 2015
This is a better solution. Thank you for pointing that out
Kristof Gheyssens   Sep 09, 2015
Maybe this solution in .htaccess reduces the page load time compared to editing the index.php? ############################################ ## SSL Redirect Loop SetEnv HTTPS on
Tom Harding   Sep 08, 2015
THANKYOU. Thankyou thankyou thankyou.
Hamzah AbuAloush   May 03, 2015
Thanks bro! just add this code above the last line in Your index.php and it will work!
David Villalpando   Feb 24, 2015
Thank you so much!! Saved me so many hours!
Alex Everitt   Feb 21, 2015
Thank you so much for posting this! I put the code above the last line of my index.php and it worked like nobody's business! Brilliant!
Share This Post
Twitter
Learning Magento
Magento Beginner's Guide
Magento Beginner's Guide
See More Details
Magento SEO
Magento SEO
See More Details
H3XED © Nick Vogt   RSS   Policies   Twitter