Using Cloudflare Workers to redirect users based on country
What are Cloudflare Workers?
Cloudflare offers a suite of products aimed at improving the speed and security of your website. One of its core features is a Content Distribution Network, allowing your website to be served from one of their 200+ edge locations distributed around the world.
Edge computing is the idea of moving compute resources closer to your users. Instead of having centralised locations where your servers are running, functions are run at the edge locations. Using edge computing for routing is one of the most common and beneficial applications – having redirections and routing rules handled closer to the user can result in a significant reduction in latency. In a traditional setup, these rules would have been handled by a service like Apache or NGINX and require managing deployments, instances, and more.
Cloudflare Workers are their edge computing solution, building on top of the CDN to allow more advanced functionality.
Example Situation
We’re running an ecommerce store, dogtreats.com, with a dedicated website and subdomain for each region we sell in, for example us.dogtreats.com and fr.dogtreats.com. When advertising our store, we want to tell people to head to our root-level domain (dogtreats.com) and have them redirected to their local store.
We want this redirect to be fast and scalable, with protection against DDoS attacks, minimal maintenance, and low costs. This is the perfect use-case for using Cloudflare Workers.
Solution
Our website is already using Cloudflare, so our setup process is reasonably simple. If yours isn’t, follow the standard Cloudflare setup first.
Creating the Worker
Once we’re ready, head to the Cloudflare Workers dashboard and click “Create a Worker”.
Using Cloudflare Workers is far simpler than using Lambda@Edge – we’re able to immediately start work on our functionality. The Cloudflare Workers dashboard is easy to use, providing a simple interface to edit and test workers.
We need to write the logic to redirect users to the correct regional store. Cloudflare adds a header called cf-ipcountry to requests, which contains the ISO-3166-1 alpha-2 country code of the user.
When we click “Save and Deploy”, our script is immediately deployed to the Cloudflare network. We can also test it using the console on the right. By default (shown above), we’re routed to the US website, but when we’re detected as being in France (shown below), we’re routed to FR.
Once you’ve deployed the script, it can be tested using the URL shown at the top of the dashboard. In our case, it’s https://shy-queen-7502.dogtreats.workers.dev/, so it can be tested using curl -v https://shy-queen-7502.dogtreats.workers.dev/ in your terminal, then look for the location header in the response, for example location: us.dogtreats.com. You can also rename your worker so it’s more easily identifiable. We’ve renamed ours to redirects.
Deploying to your website
Now that the worker is functioning, we want to make it so it’s being used by our dogtreats.com website, instead of running on the workers.dev domain. This is as simple as adding a route to our Cloudflare website.
First, head to the Workers interface within you’re Cloudflare website dashboard. Then, click on “Add route”.
A pop-up will appear, and we can configure which requests should trigger the redirects worker.
Click “Save” and Cloudflare will update to start routing requests to your worker!
How can ipdata.co help?
ipdata.co offers an ultra-fast, highly-available API for looking up the physical location of any IP address. The results returned from ipdata will be more accurate and detailed – allowing redirections to take place based on state, continent, or based on whether the user is in an EU country.
We can easily update our worker to call the ipdata API and redirect based on the response. Cloudflare workers don’t run in a standard Node.js execution environment, they implement an API similar to Service Workers. Therefore, we don’t have access to the https module, but instead we can use the Fetch API.
// Configuration to map country codes to regional stores
const regionalStores = new Map([
["US", "us.dogtreats.com"],
["FR", "fr.dogtreats.com"],
// We've added a new store to cover the rest of the European Union
["EU", "eu.dogtreats.com"]
]);
// Get an ipdata API Key from here: https://ipdata.co/sign-up.html
const IPDATA_API_KEY = "test";
addEventListener("fetch", event => {
event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
// Read the IP address from Cloudflare
const ip = request.headers.get("cf-connecting-ip");
// Get detailed information about this IP from ipdata.co
// Cloudflare exposes the standard fetch API - https://developers.cloudflare.com/workers/reference/apis/fetch/
const ipdataResponse = await fetch(
`https://api.ipdata.co/${ip}?api-key=${IPDATA_API_KEY}`
);
const ipdata = await ipdataResponse.json();
// This IP is flagged as a threat! Let's block them out
if (ipdata.threat.is_threat) {
return new Response(null, {
status: 403,
statusDescription: "Forbidden"
});
}
const ipdataCountry = ipdata.country_code.toUpperCase();
// Set our default regional store
// This is used if there's no matching store configuration
let regionalStore = regionalStores.get("US");
// Set the new regional store, if it's set in the regionalStores map
if (regionalStores.has(ipdataCountry)) {
regionalStore = regionalStores.get(ipdataCountry);
} else if (ipdata.is_eu) {
// If there's no dedicated regional store, and the user is EU-based
// let's take them to our EU store
regionalStore = regionalStores.get("EU");
}
// Redirect the user to the new URL
return Response.redirect("https://" + regionalStore);
}
Once our script has been updated, we can test it out with a couple of different IP addresses. For example, let’s check the threat blocking we’ve just added by entering a known TOR IP address.
We can also check any other IP addresses to test the other redirects.
Perfect! Everything is working as expected. Now, we can “Save and Deploy” our worker so it’s used on our main website.
Conclusions
Cloudflare Workers are powerful and easy to use. The setup process is far more user-friendly than using Lambda@Edge with CloudFront, so it’s likely to be a more appealing option for many businesses. Our redirection worker was very quick to deploy to our website and can be expanded to perform far more advanced functionality – we expanded ours to use the ipdata API which enables us to accurately redirecting based on state, continent and more. In our example, we were also able to block IP addresses which could be a threat to our business. There are a number of example workers in the Cloudflare documentation, all of which can be very useful for getting started with other use-cases such as implementing A/B testing.