Click on the Workers tab and then Add Route:
Enter the path to the subdirectory you want to protect, including a * at the end to ensure all recursive content is protected (ie. 403page.com/private_directory/*
). Click Save.
Next, click Manage Workers and then Create a Worker. In the script editor on the left, paste the following code - changing the constants on the top 2 lines (YOUR_USER_NAME
and YOUR_PASSWORD
) to whatever you please:
const NAME = "YOUR_USER_NAME"
const PASS = "YOUR_PASSWORD"
/**
* RegExp for basic auth credentials
*
* credentials = auth-scheme 1*SP token68
* auth-scheme = "Basic" ; case insensitive
* token68 = 1*( ALPHA / DIGIT / "-" / "." / "_" / "~" / "+" / "/" ) *"="
*/
const CREDENTIALS_REGEXP = /^ *(?:[Bb][Aa][Ss][Ii][Cc]) +([A-Za-z0-9._~+/-]+=*) *$/
/**
* RegExp for basic auth user/pass
*
* user-pass = userid ":" password
* userid = *<TEXT excluding ":">
* password = *TEXT
*/
const USER_PASS_REGEXP = /^([^:]*):(.*)$/
/**
* Object to represent user credentials.
*/
const Credentials = function(name, pass) {
this.name = name
this.pass = pass
}
/**
* Parse basic auth to object.
*/
const parseAuthHeader = function(string) {
if (typeof string !== 'string') {
return undefined
}
// parse header
const match = CREDENTIALS_REGEXP.exec(string)
if (!match) {
return undefined
}
// decode user pass
const userPass = USER_PASS_REGEXP.exec(atob(match[1]))
if (!userPass) {
return undefined
}
// return credentials object
return new Credentials(userPass[1], userPass[2])
}
const unauthorizedResponse = function(body) {
return new Response(
null, {
status: 401,
statusText: "'Authentication required.'",
body: body,
headers: {
"WWW-Authenticate": 'Basic realm="User Visible Realm"'
}
}
)
}
/**
* Handle request
*/
async function handle(request) {
const credentials = parseAuthHeader(request.headers.get("Authorization"))
if ( !credentials || credentials.name !== NAME || credentials.pass !== PASS) {
return unauthorizedResponse("Unauthorized")
} else {
return fetch(request)
}
}
addEventListener('fetch', event => {
event.respondWith(handle(event.request))
})
Click Save & Deploy.
Then head back to the main Workers page where you set the route before. You'll notice the route you added earlier (403page.com/private_directory/*
in my case) shows the following message:
Workers are disabled on this route
Click Edit and select the worker you just made from the dropdown to assign it to that route and click Save.
Within about 10-30 seconds, you'll see a Basic Auth challenge on the route path you specified:
Sorted!
Credit to dommmel & JonasJasas for putting the rule together here.