Fixing SSL Redirect Loops and Mixed Content in PrestaShop 9 Behind a Reverse Proxy
PrestaShop 9 SSL Behind a Reverse Proxy: Solving Redirect Loops and Mixed Content
This insight summarizes a PrestaShop forum thread addressing a common issue: SSL redirect loops and mixed content errors when running PrestaShop 9 behind a reverse proxy like Traefik, Nginx, or Apache. The original poster, MigrationPro, provides a detailed solution to ensure PrestaShop correctly detects HTTPS connections when SSL is terminated at the proxy level.
The Problem: PrestaShop's Misinterpretation of Connection Protocol
When a reverse proxy handles SSL termination, PrestaShop's backend only sees HTTP traffic. This leads to PrestaShop not recognizing that the client connection is HTTPS, resulting in:
- Infinite redirect loops
- Mixed content warnings
- SSL showing as "disabled" in the Back Office
Root Cause: Missing HTTPS Detection
PrestaShop relies on the $_SERVER['HTTPS'] variable to determine if SSL is active. When behind a proxy, this variable is not set because the connection between the proxy and the PrestaShop server is unencrypted.
The Solution: A Four-Step Approach
The provided solution involves four key steps:
Step 1: Configure Your Reverse Proxy to Forward Headers
Ensure your reverse proxy forwards the X-Forwarded-Proto, X-Forwarded-For, and Host headers. Traefik typically does this automatically. For Nginx, add the following to your server configuration:
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
Step 2: Tell PrestaShop to Trust the Proxy Header
Add the following code snippet near the top of your config/defines.inc.php file:
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}
This code checks for the X-Forwarded-Proto header and sets the $_SERVER['HTTPS'] variable accordingly.
Step 3: Enable SSL in PrestaShop
Enable SSL within PrestaShop using one of the following methods:
- Option A (Console - Recommended for PS9):
php bin/console prestashop:config set PS_SSL_ENABLED --value 1 php bin/console prestashop:config set PS_SSL_ENABLED_EVERYWHERE --value 1 - Option B (Back Office): Navigate to Shop Parameters > General > Enable SSL = Yes, Enable SSL on all pages = Yes.
- Option C (SQL - if locked out):
Remember to replaceUPDATE ps_configuration SET value = '1' WHERE name = 'PS_SSL_ENABLED'; UPDATE ps_configuration SET value = '1' WHERE name = 'PS_SSL_ENABLED_EVERYWHERE';ps_with your actual table prefix if different.
Step 4: Verify Shop URL Settings
In Shop Parameters > Traffic & SEO > Shop URL, ensure both "Shop domain" and "SSL domain" are set to your public domain (without the https:// prefix).
Important Considerations
defines.inc.phpis generally more upgrade-safe thansettings.inc.php, but it's still wise to check it after PrestaShop updates.- Payment modules (like PayPal and Stripe) often check the
PS_SSL_ENABLEDsetting in the database independently. Therefore, Step 3 is crucial even if HTTPS appears to be working after Step 2. - Avoid modifying
classes/Link.phpdirectly, as changes will be overwritten during updates. - Traefik automatically forwards the
X-Forwarded-Protoheader, while Nginx, Apache, and Caddy require explicit configuration.