Configuring Token Authentication
Cloudflare Token Authentication allows you to restrict access to documents, files, and media to selected users without requiring them to register. This helps protect paid/restricted content from leeching and unauthorized sharing.
There are two options to configure Token Authentication, via Cloudflare Workers or WAF custom rules.
Option 1: Configure using Cloudflare Workers
Review the following Cloudflare Workers documentation to configure Token Authentication:
- Configure a Worker
- Use the Auth with Headers template
Option 2: Configure using WAF custom rules
To configure Token Authentication:
- Log in to the Cloudflare dashboard, and select your account and domain.
- Go to Security > WAF > Custom rules.
- Select Create rule.
- Select Edit expression above Expression Preview to switch to the Expression Preview editor.
The following example illustrates a rule that blocks any visitor that does not pass your HMAC key validation on a specific hostname and URL path. Details required for Token Authentication include:
- The path you wish to authenticate (for example,
test.domain.com/download/cat.jpg
) - The parameter name you wish the token to have (for example,
verify
) - The desired token expiration times, if any (for example, five and 20 minutes)
For the following example URL:
test.domain.com/download/cat.jpg?verify=1484063787-9JQB8vP1z0yc5DEBnH6JGWM3mBmvIeMrnnxFi3WtJLE%3D
The expression for the custom rule would be similar to the following:
(http.host eq "test.domain.com" and not is_timed_hmac_valid_v0("mysecrettoken", http.request.uri, 10800, http.request.timestamp.sec, 8))
The components of this example custom rule (using the previous example URL) include:
- Token key =
mysecrettoken
- Token expiration time =
10800
seconds http.request.uri
=/download/cat.jpg
http.request.timestamp.sec
=1484063787
- Separator:
len("?verify=")
=8
To generate tokens for the paths using this custom rule:
Python 3.8
import hmacimport base64import urllib.parseimport timefrom hashlib import sha256message = "/download/cat.jpg"secret = "mysecrettoken"separator = "?verify="timestamp = str(int(time.time()))digest = hmac.new((secret).encode('utf8'), "{}{}".format(message,timestamp).encode('utf8'), sha256)token = urllib.parse.quote_plus(base64.b64encode(digest.digest()))print("{}{}{}-{}".format(message, separator, timestamp, token))
Python 2.7
import hmacimport base64import timeimport urllibfrom hashlib import sha256message = "/download/cat.jpg"secret = "mysecrettoken"separator = "verify"timestamp = str(int(time.time()))digest = hmac.new(secret, message + timestamp, sha256)param = urllib.urlencode({separator: '%s-%s' % (timestamp, base64.b64encode(digest.digest()))})print("{}{}".format(message, param))
PHP
$message = "/download/cat.jpg";$secret = "mysecrettoken";$separator = "?verify=";$time = time();$token = $time . "-" . urlencode(base64_encode(hash_hmac("sha256", $message . $time, $secret, true)));echo($message . $separator . $token);
Implement token creation
Implementing the token creation requires the following code entered at your origin server:
PHP Version
<?php// Generate valid URL token$secret = "thisisasharedsecret";$time = time();$token = $time . "-" . urlencode(base64_encode(hash_hmac("sha256", "/download/private.jpg$time", $secret, true)));param = "verify=" . $token;?>
Python Version
import hmacimport base64import timeimport urllibfrom hashlib import sha256secret = "thisisasharedsecret"time = str(int(time.time()))digest = hmac.new(secret, "/download/cat.jpg" + time, sha256)param = urllib.urlencode({'verify': '%s-%s' % (time, base64.b64encode(digest.digest()))})
This will generate a URL parameter such as:
verify=1484063137-IaLGSmELTvlhfd0ItdN6PhhHTFhzx73EX8uy%2FcSDiIU%3D
Which you will then need to append to any URL under the domain.com/download/* path. For example:
/download/cat.jpg?verify=1484063787-9JQB8vP1z0yc5DEBnH6JGWM3mBmvIeMrnnxFi3WtJLE%3D
The token parameter must be the last parameter in the query string.
If you are on an Enterprise plan, you can test if URLs are being generated correctly on the server by:
- Setting the WAF custom rule action to Log.
- Monitoring the activity log in Security > Events.