Learning React

I come from a Perl and PHP backend background. I have moderate JavaScript experience. These are the guides that have helped me get up to speed with React. I’ve included links that explain the reasoning behind React’s way of doing things (e.g. the Virtual DOM) and how to use React itself. I’ve also given a brief rundown on the complementary tools and libraries that I’ve found essential.

The learning curve is steep, but stick with it!

My business requirement for React: Re-building mobile version of audiomack with persistent audio player that continues to play songs between page requests.


Tooling overview

  • Node.js – Allows you to run JavaScript server-side
  • React framework
  • NPM – JavaScript Libraries — your project will likely need a load of these. Manage via package.json file
  • Babel – Code transformer — allows you to write the latest JavaScript (ES6 and beyond) and also JSX. Babel transforms it to JS that all modern browsers understand.
  • Webpack – Bundle your raw application code into a package that the browser can execute — it runs Babel, minifies etc.
  • Redux – Manage application state in single place — UI and data changes stored in state tree Getting started with Redux (by Dan Abramov)
  • Sublime’s JavaScript highlighting has some issues with JSX, so install this package — React Syntax highlighting for Sublime Text

Comments and Tips

  • You probably want to render server-side for first call (efficiency & SEO reasons) Server-side rendering
  • Getting a working Vagrant VM with source code is hard (NPM installs in shared folders seem problematic)

Enable WordPress automatic updates in your Vagrant VM

If you are using Vagrant to manage VM’s for WordPress development, you’ll know that by default auto-updates of core and plugins do not work. This is because the VM’s shared folders are not writable by the web server. This is a simple thing to fix, though. Open up your Vagrant file and add the following to your config.vm.synced_folder line:

:mount_options => ["dmode=777", "fmode=666"]

So, if your config.vm.synced_folder line looked like this before:

config.vm.synced_folder "./", "/var/www", id: "vagrant-root"

Change it to this:

config.vm.synced_folder "./", "/var/www", id: "vagrant-root", :mount_options => ["dmode=777", "fmode=666"]

Then reload your VM for the change to take effect:

vagrant reload

Save 10% off FreeAgent – Small Business Online Accounting

I’ve used FreeAgent to manage my accounts for the last four years. It’s a really easy to use piece of software, and it gives great visibility into your accounts.

If you are a freelancer or small business owner, then it could save you loads of time with your book-keeping.

If you want to try FreeAgent, you can save 10% on the cost by clicking on the graphic below:

FreeAgent Small Business Online Accounting

Prevent XSS vulnerabilities in your WordPress plugin code

Note: The following article is an extract from my guide on creating secure WordPress plugins. As well as XSS, it will contain advice on avoiding SQL injection, CSRF and other vulnerabilities. You can get hold of it here: WordPress Plugin Security Handbook.

Cross Site Scripting (XSS)

The most common vulnerability found in WordPress related code is Cross Site Scripting (XSS).

XSS flaws occur whenever an application takes untrusted data and sends it to a web browser without proper validation or escaping.

XSS allows attackers to execute scripts in the victim’s browser which can hijack user sessions, deface web sites, or redirect the user to malicious sites.

There are two main types of XSS:

  1. Persistent (or Stored)
  2. Reflected

With persistent XSS, the vulnerable code will be stored server side, either in a database on on the file system, and then surfaced when a user visits a page.

With reflected XSS, an attacker crafts a specially formatted URL which is intended to cause harm once a user clicks on it.

Reflected XSS is less dangerous because it relies on an attacker convincing the victim to click on the specially crafted URL.

Both types of XSS are caused when a WordPress plugin trusts user-supplied input.

Where could user input come from?

  • GET or POST parameters in forms (for example, your admin page)
  • Cookies
  • HTTP request headers

Key lesson: Do not trust user input.

How to prevent XSS?

Whenever you are outputting user-supplied data, make sure it is properly escaped. When you’re building a user interface, at the last moment before untrusted data is dynamically added to HTML, escape it.

Let’s look at some examples of XSS vulnerabilities that have affected plugins, and have subsequently been fixed to see what we can learn.

XSS Persistent Example

Let’s take a look at an example of an XSS persistent vulnerability.


The vulnerable Plugin is called WP-Stats (version <= 2.51) In this example, the plugin has requested a URL from an admin user on the admin screen. But before displaying it, it should be escaped with esc_url to prevent XSS. Before change, we can see an option called “stats_url” being echoed out within the href attribute, after being stripped of slashes. [php] echo '<li><a href="'.stripslashes(get_option('stats_url')).'">'.__('My Blog Statistics', 'wp-stats').'</a></li>'."\n"; [/php] After the change, we can see the URL being run through the escaping method called “esc_url”. [php] echo '<li><a href="'.esc_url( get_option( 'stats_url' ) ).'">'.__('My Blog Statistics', 'wp-stats').'</a></li>'."\n";  [/php] Also, within the same plugin we see another XSS vulnerability: [html] <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>?page=<?php echo plugin_basename(__FILE__); ?>">  [/html] In this case, the PHP_SELF server super global is being echoed without being escaped. This is dangerous because a malicious user could inject dangerous code into the action just via a specially crafted URL. Example:


Would lead to the HTML form tag looking like this:

<form method=“post” action=“/form.php”><script>alert(‘Vulnerable’);</script>?page=…

After the fix:

<form method="post" action="<?php echo admin_url( 'admin.php?page='.plugin_basename( __FILE__ ) ); ?>"> 

Key lesson: Don’t echo PHP_SELF into form action attributes. Use esc_url or as above, admin_url if the page is an administration page.

Example XSS (Reflected)


QTranslate is a plugin for helping manage language translation throughout your site.

The edit GET parameter is not sanitised before being show to a user. A specially craft URL like the one below can be used to inject malicious code into the page.


To prevent this, the esc_html function should be used before echoing out the contents of “edit” parameter to the user on the options-general.php page.

YOP Poll

YOP Poll allows you to add surveys to your site.

Echoing out user-supplied data in Javascript:

                function close_window() { 
                    var yop_poll_various_config = new Object(); 
                    yop_poll_various_config.poll_id = '<?php echo yop_poll_base64_decode( $_GET['poll_id'] )                                    ?>'; 

Fixed version:

yop_poll_various_config.poll_id = '<?php echo esc_js(yop_poll_base64_decode( $_GET['poll_id'] ))                                ?>';

Key lessons

Encode data before use in a parser ( JS, CSS , XML )

You are writing data into HTML attributes, use:


You are writing data into HTML, use:


You are writing user supplied data into JavaScript, use:


You are asking a user for a URL and writing it into HTML, use:

esc_url_raw / esc_url



Further reading

WordPress Plugin Security Handbook

TLS Performance Checklist

From High Performance Browser Networking by Ilya Grigorik:

  • Upgrade TLS libraries to latest release, and (re)build servers against them.
  • Enable and configure session caching and stateless resumption.
  • Monitor your session caching hit rates and adjust configuration accordingly.
  • Configure forward secrecy ciphers to enable TLS False Start.
  • Terminate TLS sessions closer to the user to minimize roundtrip latencies.
  • Use dynamic TLS record sizing to optimize latency and throughput.
  • Ensure that your certificate chain does not overflow the initial congestion window.
  • Remove unnecessary certificates from your chain; minimize the depth.
  • Configure OCSP stapling on your server.
  • Disable TLS compression on your server.
  • Configure SNI support on your server.
  • Append HTTP Strict Transport Security header.

Re-enable Apache & PHP Web Sharing on OS X Yosemite

The Web Sharing feature is a useful way of testing out simple sites and applications using the built-in Apache server in OS X. Although I don’t recommend using it for complex projects (I recommend Vagrant for those cases), it’s still a useful thing to have.

After upgrading from from Mavericks to Yosemite, the built in web server no longer was configured to serve content from /Users/(username)/Sites. Here are some brief instructions on getting it back up and running:

First, it’s worth noting that Yosemite is now using Apache 2.4 rather than 2.2, which was included in Mavericks. This has an effect on some authorisation settings, which you will see below.

As an administrator, load the following file in an editor:


Uncomment the following line:

Include /private/etc/apache2/users/*.conf

Edit the following file


Uncomment the following lines:

LoadModule userdir_module libexec/apache2/mod_userdir.so
LoadModule php5_module libexec/apache2/libphp5.so
Include /private/etc/apache2/extra/httpd-userdir.conf

Edit your user configuration under /etc/apache2/users/username.conf

Change any instances of:

Order allow,deny
Allow from all


Require all granted

(this was one of the major changes between Apache 2.2 and 2.4 — see more details here http://httpd.apache.org/docs/2.4/upgrading.html)

Re-instate your previous PHP configuration:

sudo mv /etc/php.ini-5.2-previous /etc/php.ini

If you want to have Apache startup automatically when you Mac boots, enter the following:

sudo launchctl load -w /System/Library/LaunchDaemons/org.apache.httpd.plist

Finally, start Apache:

sudo apachectl start

If all goes well, you’ll see a message similar to this logged in /var/logs/apache2/error_log:

[Mon Oct 20 07:26:42.063040 2014] [mpm_prefork:notice] [pid 4412] AH00163: Apache/2.4.9 (Unix) PHP/5.5.14 configured -- resuming normal operations

You should also now be able to access your shared files in your browser via http://localhost/~username/

Any questions? Please use the comments section below!

P.S. – Looking for reliable hosting for your PHP projects? I recommend Clook:

Composing Simple HTML Mails in MailChimp

MailChimp is a great tool, but it has an over-reliance on fancy templates. When sending emails, I’ve found that simpler text-based e-mails are more effective as they look more like a personal e-mail. However, getting this simple look with MailChimp is not immediately obvious. In this guide, I’ll show you how you can compose a mail so it looks like a regular Gmail message.

Here’s what an example mail looks like using this simple method:


To do this, you need to use MailChimps Code Your Own option when it comes to the design stage. You then need to select the Paste in code option.

This gives you a text box into which you can compose your e-mail, marking it up with simple HTML tags. Here is the HTML that I used for the mail shown above:

<h1>This is a header</h1>
<h2>A smaller header</h2>
<p>Use p tags for the paragraphs of your e-mail.  You can also link to URL's with the a tag : <a href="http://google.com/">Google</a></p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut egestas a neque sit amet luctus. In eget justo a felis tempor gravida. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur sed feugiat enim, et semper nisl. Sed tempus arcu id magna mollis, ut viverra tellus rutrum. Nullam dui massa, ullamcorper id neque non, elementum lobortis nisl. Duis venenatis diam vel vehicula suscipit.</p>
<p>Vestibulum sit amet arcu felis. Maecenas dictum lobortis tempus. Praesent in eleifend velit. Sed facilisis diam non iaculis iaculis. Donec sit amet nisi metus. Mauris auctor erat non sollicitudin ultrices. Vestibulum gravida ullamcorper augue, ac placerat sapien consectetur nec.</p>
<p>Using lists:</p>
<li>Unordered list item 1</li>
<li>Unordered list item 2</li>

<li>Ordered list item 1</li>
<li>Ordered list item 2</li>
<p>You can apply <strong>bold</strong> or <em>italics</em> too!</p>
<p>Use br tags to create more space between paragraphs</p>
<p>That's it!</p>
<p><a href="http://www.glenscott.co.uk/">Glen Scott</a> - <a href="http://yellowsquare.info">Yellow Square</a></p>
<p><a href="*|UNSUB|*">Unsubscribe from this list </a></p>

Note: You only need to include the *|REWARDS|* tag if you are on the free MailChimp plan, otherwise you can omit it.

That’s it! I hope you found this guide useful.

Follow the bright spots

Chip and Dan Heath make a great point in their book about changing behaviour that you need to follow the bright spots:

Investigate what’s working and clone it

It’s something that I’ve realised is really important when you are running an online service like FreelanceDevLeads.

Since I launched at the beginning of the year, I’ve been focussing on finding out:

  • Why people are signing up for the free examples, and not paying for the full service
  • Why people are signing up and then cancelling after a month
  • Why people are visiting my landing page and not signing up at all

All of these issues are related to people that are not necessarily a great fit for my service.

The fact is, my service is not for everybody.

I should be focusing on the customers who are getting value from the service and have been quite happily using the service for months. These are the people that will give me the greatest insight on how to grow and improve the service.

6 Reasons to Turn Down That Freelance Project


Over the last year I’ve had several discussions with potential clients about projects that for one reason or other were not right for me. Sometimes I could tell within minutes of the first contact with the client that the fit was not right. Other times, it has taken weeks of qualifying before finally saying “no”.

Here are five examples of projects I’ve turned down, and reasons why you may want to too:

1. Working for equity

This seems to be a very common request from startups who have not yet secured any funding. They are looking to build prototypes or MVP’s, and do not have any cash for development. Instead, they promise equity in the company. Sadly, equity does not put food on the table for me or my family, so this arrangement is never going to work for me.

2. Clients that do not seem business savvy

Let’s call this the “hunch” that you get when you first talk to a client. More often a not, if you get an impression that the project owner is winging it, then things are not likely to run smoothly. Better to bail out sooner rather than later.

3. Project requirements are not aligned with skills

Sometimes projects come in that sound amazing, but the only issue is that the skills required are not quite what you have. Its tempting to take on the project anyway, but this is likely to lead to difficulties further on down the line.

4. Ethical or moral reservations

Betting sites. Debt-collecting agencies. Two examples of businesses that I’ve refused to work with for ethical reasons.

5. Hourly billing

I used to work with some clients on an hourly basis. These days, I only allow myself to be booked daily or weekly. Why? Hourly billing inevitably leads to a feeling of being micro-managed. Being diligent and tracking your time hourly is very difficult. Allowing a client to book you for a day or more allows you to completely focus on their project during that time.

6. Recruitment agencies

I have always preferred worked with clients directly. Working with a recruitment agent means you are essentially dealing with a middleman. This can often lead to communication issues — the recruiter may be selling you a project that is not quite what the end client is expecting. They also take a big chunk of the client’s budget for their own cut. Avoid these issues, and deal with clients directly.

What kind of projects have you turned down or would refuse to work on? Let me know in the comments section below!

Want to get freelancing tips from me? (no more than 1 e-mail a month, I promise!)

photo credit: No by sboneham on Flickr

Securing your PHP REST API with OAuth


There are many considerations to make when building and securing a public-facing API, but I wanted to look at one issue in particular: Making sure that only authenticated clients can access it.

Ideally, we want to make one request to the server and get back one response. In order to have a simpler application flow, we want to avoid the added complexity of managing access tokens.

  1. Client sends a request for data along with their authentication details
  2. Server sends data back to the authenticated client

This flow will be familiar if you have used Amazon Web Services (AWS) before, as they use a similar “signed-message” solution.


Use a simple version of the OAuth 1.0 standard which is known as “2-legged” authentication. In this system, no access tokens are used. Authentication is performed using a public and private key system. These public and private keys are known by the client (consumer) and the server (provider).

Things to note:

  • The private key (the secret) is NEVER passed over the wire
  • The private key is used in combination with HMAC to hash the request data being sent to the API
  • The server uses its own copy of the private key to verify the request is authentic
  • You should use SSL to encrypt traffic between your consumer and provider

My solution uses PHP OAuth library by Andy Smith (MIT licence) for the heavy lifting. I have made this library available as a Composer package: https://packagist.org/packages/glenscott/oauth.

Here are two simple examples for the provider and consumer sides:

Provider side

In this example, the list of valid consumer keys and secrets are hardcoded, but you probably want to store these in a DB somewhere. The provider will return "true" if it is a valid authenticated request, or otherwise it will spit out and error message "Exception: ...".

		$server = new OAuthServer(new DataApi_OAuthDataStore());
		$server->add_signature_method( new OAuthSignatureMethod_HMAC_SHA1() );

		$request = OAuthRequest::from_request();

		try {
			if ( $server->verify_request($request) ) {
				echo json_encode(true);
		catch (Exception $e) {
			echo json_encode("Exception: " . $e->getMessage());

		class DataApi_OAuthDataStore extends OAuthDataStore {
			function lookup_consumer($consumer_key) {
				$consumer_secrets = array( 'thisisakey'		=> 'thisisasecret',
										   'anotherkey'		=> 'f3ac5b093f3eab260520d8e3049561e6',

				if ( isset($consumer_secrets[$consumer_key])) {
					return new OAuthConsumer($consumer_key, $consumer_secrets[$consumer_key], NULL);
				else {
					return false;

			function lookup_token($consumer, $token_type, $token) {
				// we are not using tokens, so return empty token
				return new OAuthToken("", "");

			function lookup_nonce($consumer, $token, $nonce, $timestamp) {
				// @todo lookup nonce and make sure it hasn't been used before (perhaps in combination with timestamp?)
				return NULL;

			function new_request_token($consumer, $callback = null) {


			function new_access_token($token, $consumer, $verifier = null) {


Consumer side

	require_once dirname(__FILE__) . '/../library/OAuth/OAuth.php';

	// this is sent with each request, and doesn't matter if it is public
	$consumer_key = 'thisisakey';

	// this should never be sent directly over the wire
	$private_key  = 'thisisasecret';

	// API endpoint
	$url = 'https://example.com/v1/oauth';

	// the custom paramters you want to send to the endpoint
	$params = array( 'foo' => 'bar',
					 'bar' => 'foo',

	$consumer = new OAuthConsumer($consumer_key, $private_key);
	$request  = OAuthRequest::from_consumer_and_token($consumer, NULL, 'GET', $url, $params);

	$sig = new OAuthSignatureMethod_HMAC_SHA1();

	$request->sign_request($sig, $consumer, null);

	$opts = array(
		'http' => array(
			'header' => $request->to_header()

	$context = stream_context_create($opts);

	$url = $url . '?' . http_build_query($params);

	echo "Making request: " . $url . PHP_EOL;
	echo "Authorization HTTP Header: " . $request->to_header() . PHP_EOL;
	echo "Response: " . file_get_contents($url, false, $context) . PHP_EOL;

Using the samples above should give you a head-start when creating your own authenticated API.

View the sample code on GitHub.

Any questions? Please use the comments section below!

P.S. – Looking for reliable hosting for your PHP projects? I recommend Clook: