Search code examples
wordpressamazon-web-services.htaccesshttpsamazon-elastic-beanstalk

HTTPS on Wordpress hosted on AWS Elastic Beanstalk


I'm trying to force https over HTTP protocol for my website. I have managed to force the http://example.com => https://example.com and all blog post URLs.

However, when I try to access https://example.com/wp-admin, it says example.com redirected you too many times. ERR_TOO_MANY_REDIRECTS.

Please note that:

  • My local development and AWS Elastic Beanstalk are connected to the same database.
  • localhost and localhost/wp-admin works fine and can log in to admin panel successfully.
  • I have setup an environment variable WP_ENV to determine if it is a local or production environment.

Here is my setup of my wp-config.php file.

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
    $_SERVER['HTTPS'] = 'on';

/** HTTPS  */
if (getenv('WP_ENV') == 'production'){
    define('FORCE_SSL_ADMIN', true);
    define('FORCE_SSL_LOGIN', true);
    define('WP_HOME', 'https://example.com');
    define('WP_SITEURL', 'https://example.com');
}

if(getenv('WP_ENV') == 'development'){
    /* Http only.  */
    define('WP_HOME', 'http://localhost');
    define('WP_SITEURL', 'http://localhost');
} 

And here is my .htacess

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

<If "%{HTTPS} == 'on'">
# For a site running on port 80 (http)
    RewriteCond %{SERVER_PORT}  ^80$
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^wp-(admin|login|register)(.*) https://example.com/wp-$1$2 [L]
</If>

RewriteCond %{SERVER_PORT}  ^80$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

</IfModule>

# END WordPress

Solution

  • Try the following instead in your .htaccess file:

    # Redirect HTTP to HTTPS (all requests)
    RewriteCond %{HTTP:X-Forwarded-Proto} ^http$
    RewriteRule ^ https://example.com%{REQUEST_URI} [R=302,L]
    
    # BEGIN WordPress
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    
    # Prevent additional filesystem check
    RewriteRule ^index\.php$ - [L]
    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
    </IfModule>
    # END WordPress
    

    This assumes you are behind a load balancer/proxy that handles the SSL connection and the connection to your application server is actually over non-encrypted HTTP (which is why the standard checks against HTTPS or SERVER_PORT server variables appear to fail). The proxy (in front of your application server) sets the X-Forwarded-Proto header, informing the backend application server the nature of the connection to the client.

    Change the 302 (temporary) to 301 (permanent) only when you are sure it's working OK in order to avoid caching issues.

    With WordPress you should avoid editing the directives in the # BEGIN WordPress section as WordPress will try to overwrite this when it updates (unless you have taken additional steps to block this).