Posted on Leave a comment

Switching WordPress to https only

Wordpress Logo

As you might have seen I’ve switched this site to https only. The steps involved in switching WordPress to https only are pretty simple.

Set Site URL

First, make sure to set the proper https site URLs. You find these options under Settings » General: Wordpress set site URL to https

Redirect non-https traffic

Second, make sure to redirect all non-https requests to https-only in your .htaccess file. In the example below I’ve included an automatic redirect to the www subdomain for the SSL certificate. You can safely ignore this step in case you have a different setup:

 
RewriteEngine On
RewriteBase /

RewriteCond %{HTTP_HOST} !^www.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

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

Update media URLs

Afterwards, you (probably) need to update the URLs of your referenced media files in your blog posts/pages. Do so by issuing the following command (of course replace with your proper domain):

UPDATE wp_posts SET post_content = 
replace(post_content, 'http://www.YOUR-DOMAIN.com', 'https://www.YOUR-DOMAIN.com');

Update template and plugins

Finally, you need to make sure that your theme and respective plugins do not statically reference any http-only files, e.g. fonts.google, etc. For instance, for the tiga-theme that this site’s is derived from you need to overload the Google fonts URL set by enqueue.php (replace http:// with // only):

wp_enqueue_style( 'tiga-font', 
'//fonts.googleapis.com/css?family=Francois+One|Open+Sans:400italic,400,700', 
null, TIGA_VERSION, 'all' );

That’s it 😉

Posted on 1 Comment

Enabling Cross-Origin Resource Sharing CORS for Apache

Apache Logo

When trying to share resources across different domains (host-a.com vs. host-b.com) you will come across the concept of Cross-Origin Resource Sharing (CORS). In order to be able to share resources across different domains you will most likely need to enable to CORS manually on your server. For instance, when a script on host-a.com tries to access resources on host-b.com CORS needs to be enabled on host-b.com. This post shows you the steps needed for enabling Cross-Origin Resource Sharing CORS for Apache using a .htaccess file.

Note: Looking for a way to enable CORS for PHP? Have a look at Enabling Cross-Origin Resource Sharing CORS for PHP.

Prepare your .htaccess

In order to to enable CORS on Apache you need mod_headers and mod_setenvif. The example below show you how to prepare Apache for the two types of CORS requests:

  1. Pre-Flight Requests
  2. Simple Requests

Pre-Flight Requests are generated on the client side when not using GET, POST and HEAD requests on external domain resources (or setting custom headers). In this case we need to check Access-Control-Allow-Headers and Access-Control-Allow-Methods in order to allow or disallow CORS requests to our server. Second, simple requests handle GET, POST and HEAD requests across different domains. In this case we need to check the Origin header and set Access-Control-Allow-Origin correspondingly to allow such CORS requests. Below you find examples to allow CORS for method-a Pre-Flight Requests and simple requests from host-a.local or host-b.local, optionally for accessing different remote scripts too (e.g. https://host-b.local/method-a.php).



   ##########################################################################
   # 1.) ENABLE CORS PRE-FLIGHT REQUESTS
   # e.g. PUT, DELETE, OPTIONS, ...
   # we need to set Access-Control-Allow-Headers and 
   # Access-Control-Allow-Methods for allowed domain(s)
   ##########################################################################
   
   # first check for pre-flight headers and set as environment variables
   # e.g. header method-a is set here
   SetEnvIf ^Access-Control-Request-Method$ "method-a" METHOD_A
   SetEnvIf ^Access-Control-Request-Headers$ "^Content-Type$" HEADER_A

   # set corresponding response pre-flight headers for allowed domain(s)
   Header set Access-Control-Request-Methods "method-a" env=METHOD_A
   Header set Access-Control-Request-Headers "content-type" env=HEADER_A
   
   # TODO: add allowed additional pre-flight requests here...
   
   #########################################################################
   # 2.) ENABLE CORS *SIMPLE REQUESTS* (vs. Pre-Flight Requests from above)
   # e.g. GET, POST and HEAD requests
   # we need to set Access-Control-Allow-Origin header for allowed domain(s)
   # also note that POST requests need to match one of the following 
   # Content-Type: 
   # 1) application/x-www-form-urlencoded
   # 2) multipart/form-data
   # 3) text/plain
   #########################################################################
   
   # write line for each domain you would like to enable CORS requests for
   # e.g. origin = http://host-a.local or http://host-b.local 
   SetEnvIfNoCase Origin "((http(s?))?://(www\.)?(host\-a|host\-b)\.local)(:\d+)?$" AccessControlAllowOrigin=$0
   Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
   
   # e.g. origin = https://host-b.local/method-a.php
   SetEnvIfNoCase Origin "https://host-b.local/method-a.php" AccessControlAllowOrigin=$0
   Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
   
   # generic regexp match for more flexibel use cases
   #SetEnvIfNoCase Origin "((http(s?))?://(www\.)?(host\-a|host\-b)\.local)(:\d+)?$" AccessControlAllowOrigin=$0
   #Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
 
   # TODO: add additional allowed simple requests here...
 

Test File

In case you want to test this CORS setup here’s a simple test file:

<script src="//code.jquery.com/jquery-1.11.0.min.js"></script><script>// <![CDATA[
function a() {
var jqxhr = $.get( "http://host-b.local", function() {
})
.done(function() {
alert( "second success" );
})
.fail(function() {
alert( "error" );
})
}

function b() {
var jqxhr = $.get( "http://host-b.local/method-b", function() {
})
.done(function() {
alert( "second success" );
})
.fail(function() {
alert( "error" );
})
}
// ]]></script><a>Host B (GET)</a> <a>Host B / Method A (GET)</a>

Be sure to configure your Apache VHost settings accordingly.

Improvements

Since we don’t want to manually edit .htaccess files a simple configuration script would be nice to set domain configurations automatically for CORS enabled domains/methods.

Posted on 1 Comment

Custom WordPress Permalinks Are Causing 403 or 404 Errors

Wordpress Logo

When settings custom permalink structures in your WordPress settings make sure to

  1. either make .htaccess writeable by your webserver so that when saving your custom structure via the backend WordPress will automatically update your .htaccess too
  2. or manually edit your .htaccess file with the minimal required mod_rewrite rules as shown below, right after setting your custom permalink structure via the backend
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Also, make sure that your RewriteBase setting is correct.

Hint:
In case you experience 403/404 errors after setting your custom permalink structure here is what you can do:

  1. open options table from database and locate the permalink_structure field
  2. clear its value and save the entry
  3. remove the above mod_rewrite content from .htaccess
  4. make .htaccess writeable by your webserver
  5. reload your backend URL (/wp-admin)

This way you can reset your permalink structure to “Default” setting and start over again.