As we’re now running a plugin shop here on yoast.com, selling our Video SEO plugin, Tag optimizer and soon more, we also have a checkout page. I wanted that checkout page to run on https, for obvious reasons: people fill out their email and, depending on their payment method, their credit card details there. That deserves more security. It turned out not to be as simple as I wanted it to be, but I fixed it. This posts documents my mistakes and issues with my WordPress SSL setup in the hope of preventing you from making them.
You might think: couldn’t I just always load that image over SSL? Yes you could, but that’d be slower, which is why I chose not to do it.
Getting an SSL certificate on your server
This is by far the geekiest bit of this entire process, and not something I want to explain completely. In fact, I didn’t even do this myself. Just like all other VPS.net customers, you can get a free Comodo SSL certificate, all you have to do is file a support request for your VPS. It’s one of the reasons why I think VPS.net delivers the best WordPress hosting out there. BTW, they’re running a special at VPS.net, giving away Amazon gift cards for new VPSes, so if you’ve been thinking about switching, now’s a better time than any to switch to VPS.net.
I had already set up the free certificate a while back, as I wanted to run my WordPress admin over https, but I decided to go for a Extended Validation certificate today. This is a certificate that doesn’t just show an SSL icon in the browsers location bar but actually gives a green background for it and adds the company’s name, like so:
Of course this isn’t needed for every site, but I think it’s worth testing if you sell products. It provides just that bit of extra trust that can be so needed for online transactions.
Next: forcing SSL on that one page
There are plugins that can do this for you, most notably WordPress HTTPS, but as I wanted a bit more control and understanding of what was happening, I decided to code it manually. The code consists of two bits, this bit forces the checkout page to be on https all the time and at the same time redirects all pages that do not need to be SSL to an http URL:
function yst_ssl_template_redirect() { if ( is_page( 123 ) && ! is_ssl() ) { if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) { wp_redirect(preg_replace('|^http://|', 'https://', $_SERVER['REQUEST_URI']), 301 ); exit(); } else { wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], 301 ); exit(); } } else if ( !is_page( 123 ) && is_ssl() && !is_admin() ) { if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) { wp_redirect(preg_replace('|^https://|', 'http://', $_SERVER['REQUEST_URI']), 301 ); exit(); } else { wp_redirect('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], 301 ); exit(); } } } add_action( 'template_redirect', 'yst_ssl_template_redirect', 1 );
If you’re sure the URL will always be “clean”, as in, without parameters, this can be even simpler, but in this case I needed it to work with the URL parameters that Easy Digital Downloads uses. The number 123 is the ID of the checkout page, you should of course replace with your own page ID if you use this code.
Now we also want get_permalink to return the right URL, so let’s filter its output:
function yst_checkout_page_ssl( $permalink, $post, $leavename ) { if ( 123 == $post->ID ) return preg_replace( '|^http://|', 'https://', $permalink ); return $permalink; } add_filter( 'pre_post_link', 'yst_checkout_page_ssl', 10, 3 );
This way if something links to the checkout page, the redirect isn’t even needed as the link is already an https link.
MaxCDN, W3 Total Cache & SSL: a golden trio
My favourite WordPress CDN provider MaxCDN, works great with W3 Total Cache. It does so even with SSL, if you know how to set it up. It’s very bloody simple too once you know it: for each CNAME, you enter not just the CNAME, but you follow it by a comma, and then enter the SSL version. For me, this looks like this (click for larger version):
This settings makes W3 Total Cache use the first hostname for http requests, and the second one for https. With a rather image heavy site like this one that’s a golden thing.
Broken SSL: fixing links in theme files
If you load a page over SSL, all the other files that are loaded on that page should also be loaded over SSL for it to not be “broken”. This means that every single image, javascript file, stylesheet etc. needs to be loaded over SSL. WordPress will fix a lot of this for you, but you’ll probably encounter some issues, as did I, causing a broken SSL icon in the location bar, as shown above here.
In my case, within my theme’s stylesheet, I was loading a google web font file. That shouldn’t be an issue, of course, but I was loading that font file over http, instead of using what’s called a protocol relative link. Every time you’re embedding images, javascript or CSS files, you should be using a protocol relative link. Instead of linking to:
http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600
I’m now linking to:
//fonts.googleapis.com/css?family=Source+Sans+Pro:400,600
As you can see, I left out the http:, this will make the browser use the current protocol to fetch that file. This means that when a user is on plain http, it’ll use that, which is faster, but if the user is on https, it’ll use the safe https link.
Bonus: WordPress SSL setup for the admin panel
Now that you’ve set all this up, you might as well use that SSL certificate for your admin too. That part is actually pretty easy. Just drop this in the wp-config.php:
define('FORCE_SSL_ADMIN', true);
That’ll force the entire admin over SSL, which is what you want in most cases. If that is too slow for you though, you could also decide to just force the login page over SSL:
define('FORCE_SSL_LOGIN', true);
This will force the login and registration pages to be SSL. I think you should go for the first option though, and run your entire admin over SSL.
Conclusion: WordPress SSL setup is easy, do it!
With all these tips, there’s really no reason anymore why you couldn’t run any page where a user submits private data on SSL. So, just do it!
WordPress SSL setup tips & tricks is a post by Joost de Valk on Yoast - Tweaking Websites. A good WordPress blog needs good hosting, you don't want your blog to be slow, or, even worse, down, do you? Check out my thoughts on WordPress hosting!