├── package.json ├── README.md └── index.js /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cloudflare-worker-basic-auth", 3 | "version": "1.0.1", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "dependencies": {} 7 | } 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Most of the code has been copy-pasted from https://github.com/jshttp/basic-auth 2 | 3 | # Why 4 | 5 | I use it to protect static html pages. 6 | 7 | # Usage 8 | 9 | 1. Set credentials in `index.js` 10 | ``` 11 | const NAME = "super" 12 | const PASS = "secret" 13 | ``` 14 | 3. Save and copy `index.js` to your cloudflare worker and deploy 15 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const NAME = "super" 2 | const PASS = "secret" 3 | 4 | /** 5 | * RegExp for basic auth credentials 6 | * 7 | * credentials = auth-scheme 1*SP token68 8 | * auth-scheme = "Basic" ; case insensitive 9 | * token68 = 1*( ALPHA / DIGIT / "-" / "." / "_" / "~" / "+" / "/" ) *"=" 10 | */ 11 | 12 | const CREDENTIALS_REGEXP = /^ *(?:[Bb][Aa][Ss][Ii][Cc]) +([A-Za-z0-9._~+/-]+=*) *$/ 13 | 14 | /** 15 | * RegExp for basic auth user/pass 16 | * 17 | * user-pass = userid ":" password 18 | * userid = * 19 | * password = *TEXT 20 | */ 21 | 22 | const USER_PASS_REGEXP = /^([^:]*):(.*)$/ 23 | 24 | /** 25 | * Object to represent user credentials. 26 | */ 27 | 28 | const Credentials = function(name, pass) { 29 | this.name = name 30 | this.pass = pass 31 | } 32 | 33 | /** 34 | * Parse basic auth to object. 35 | */ 36 | 37 | const parseAuthHeader = function(string) { 38 | if (typeof string !== 'string') { 39 | return undefined 40 | } 41 | 42 | // parse header 43 | const match = CREDENTIALS_REGEXP.exec(string) 44 | 45 | if (!match) { 46 | return undefined 47 | } 48 | 49 | // decode user pass 50 | const userPass = USER_PASS_REGEXP.exec(atob(match[1])) 51 | 52 | if (!userPass) { 53 | return undefined 54 | } 55 | 56 | // return credentials object 57 | return new Credentials(userPass[1], userPass[2]) 58 | } 59 | 60 | 61 | const unauthorizedResponse = function(body) { 62 | return new Response( 63 | body, { 64 | status: 401, 65 | headers: { 66 | "WWW-Authenticate": 'Basic realm="User Visible Realm"' 67 | } 68 | } 69 | ) 70 | } 71 | 72 | /** 73 | * Handle request 74 | */ 75 | 76 | async function handle(request) { 77 | const credentials = parseAuthHeader(request.headers.get("Authorization")) 78 | if ( !credentials || credentials.name !== NAME || credentials.pass !== PASS) { 79 | return unauthorizedResponse("Unauthorized") 80 | } else { 81 | return fetch(request) 82 | } 83 | } 84 | 85 | addEventListener('fetch', event => { 86 | event.respondWith(handle(event.request)) 87 | }) 88 | --------------------------------------------------------------------------------