Enable Complete support for SSL on Wordpress
Thursday, August 5, 2010 at 20:18 By 'complete' I mean: required SSL on the login and register pages as well as the entire admin section, and optional SSL for the entire blog for private reading. And when there is SSL, everything is transfered over SSL.
The first step is to enable SSL for administration. This is well documented within Wordpress, just add the following statement to your wp-config.php:
define('FORCE_SSL_ADMIN', true);
This will also force the links to the login, register, and forgot password pages to show up as 'https'. Wordpress will also force SSL if you navigate to the pages directory.
The second step is to set the relative options, settings, and constants to enable optional support for private browsing. Unfortunately Wordpress has no 'if https, only https' switch. Such that if you try to use 'https://yourblogurl.tld" the page may include images and plugin content over http causing a 'partial' SSL session (this is no good). We CANNOT enable private browsing if images are still transfered in clear-text.
This is a bit of a hack, and it looks a bit annoying. If you have a better engineered solution please let me know. Open your wp-config again and towards the top add:
define('WP_SITE_URI', ($_SERVER["HTTPS"]?"https://":"http://").$_SERVER["SERVER_NAME"]);
define('WP_SITEURI', ($_SERVER["HTTPS"]?"https://":"http://").$_SERVER["SERVER_NAME"]);
You could abstract out your domain if you'd like. This example assumes your blog is located in the top directory. Add a sub-directory at the end if you require. Then somewhere BEFORE the include for 'wp-settings' insert:
define("WP_CONTENT_URL", WP_SITE_URI . "/wp-content");
Then after the include of 'wp-settings' add:
wp_cache_set("siteurl_secure", "https://" . $_SERVER["SERVER_NAME"], "options");
wp_cache_set("home", WP_SITE_URI, "options");
wp_cache_set("siteurl", WP_SITE_URI, "options");
Yes, I know SERVER_NAME is repeated. I too feel dirty for having to add so much to Wordpress's configuration. The lead to rewrite the cache values was from noctis' blog (interesting that he does not support optional SSL).
Explanation: The optional part is the killer, since you want the ability to serve Wordpress in clear-text you need to make sure your 'siteurl' setting is set to use 'http://'. This setting is pulled from the database and used to set a constant called 'WP_CONTENT_URL'. Other constants will also inherit the 'http://' from WP_CONTENT_URL. Since constants are as they sound, you need to set it correctly before 'wp-settings' queries the database for the wrong value. However you must wait until 'wp-settings' includes the necessary functions to manipulate the cache. This is why we must wrap the include for 'wp-settings' to change all possible setting variables to support either HTTP or HTTPS.
Not done yet? Of course not! The last change is implemented as a plugin. (You could add it anywhere really.) We need to add a filter to replace all uploaded content to run over either HTTP or HTTPS. Whenever you insert an image into a post a corresponding <img src="http://" will be hard-coded into the post (if your saved 'siteurl' uses 'http://'). Create a plugin folder, name it something like 'content over ssl'. Inside create a like-named php file and inside include:
<?php
/* Plugin Name: Content over SSL
* Description: Re-write content URIs to use the appropriate protocol
* Author: Me
* Version: .1
*/
add_filter('the_content', 'my_ssl');
function my_ssl($content) {
if (isset($_SERVER["HTTPS"]))
$content = ereg_replace("http://" . $_SERVER["SERVER_NAME"], "https://" . $_SERVER["SERVER_NAME"], $content);
return $content;
}
?>
This will rewrite any hard-coded links in your post's content, to your domain name, to use HTTPS if the page is called using HTTPS. Remember to enable the plugin you just created in the Wordpress administration menus.
This was tested on Wordpress 3.0 running on Apache. Note: you'll need to setup SSL support yourself. :)
Ted |
7 Comments |
ssl,
vip,
wordpress in
Hacks / Tips,
Technology 

Reader Comments (7)
I've added the FORCE_SSL_ADMIN to the config file but I'm not sure what it's supposed to do. I can still go to http://domain.com/wp-login.php and login and run the admin interface over insecure HTTP.
It's only supposed to change the login link on the front page and such?
Please help :)
I'm running WP 3.0.1
Dave: According to the documentation over at Wordpress.org, FORCE_SSL_ADMIN should redirect the login and admin pages to https.
The documentation suggests that Wordpress should not allow you to use the login portal over http (even if you navigate directly). "The constant FORCE_SSL_ADMIN can be set to true to force all logins and all admin sessions to happen over SSL." - From http://codex.wordpress.org/Administration_Over_SSL
So I'm not sure why you're running into trouble. Alternatively you can add a redirect in .htaccess that forces logins over SSL yourself. (not tested)
RewriteCond %{HTTP_HOST} ^domain.com/wp-login.php [NC]
RewriteRule ^(.*)$ http://domain.com/wp-login.php$1 [L,R=301]
quick question... i am runnning a multi site with 2 networks... Network 1 has a ssl but network 2 does not..
I have forced ssl over admin and isolated it to network 1 only since that is the domain with the ssl.
I also need now to force ssl via the site url and home url of all newly created sites in network one without if affecting network2..
Can you tell me how to do this using nework1 and network2 as examles..
Can this all be done via the wp config file... I know how to do it via htaccess but it does it globably and I cant have it affecting network2
Thanks Scott
ps.. this is what i used for the wp admin and login area.. just need something similiar to make this happen for all the pages and uploads.. I dont want to have to go into superadmin and manually change the site url and home url evertime someone creates a blog on my network
if ( $_SERVER["HTTP_HOST"] == "example.com" ) {
define('FORCE_SSL_ADMIN', true);
}
Dave.. i believe you need a ssl cert on your domain to even use this !
performance will suffer due to the nature of HTTPS. It would be much wiser to place the secure content in a subdomain and secure the subdomain directory. Then bots and crawlers will not ding you for speed.
Just a thought. but a separate secure site is also a better idea for the shopping cart and other plug ins. marketing and seo plugins tend to conflict with cart, and other functional plugins
Thanks
Omprakash