Last active
June 8, 2023 19:00
-
-
Save teidesu/5e7becbd6ae9f24d5925e69e71a95285 to your computer and use it in GitHub Desktop.
web-based password protection, in pure nginx, with php support
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dummy file for gist title |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
limit_req_zone $binary_remote_addr zone=phpfront_auth:10m rate=1r/s; | |
map $arg_login:$arg_password $phpfront_logpass_to_token { | |
"user1:SOME_PASSWORD" "SOME_SECRET"; | |
"user2:SOME_PASSWORD" "SOME_SECRET"; | |
default 0; | |
} | |
map $cookie_secure $phpfront_secure_access { | |
"SOME_SECRET" 1; | |
"SOME_SECRET2" 1; | |
default 0; | |
} | |
server { | |
listen 80; | |
server_name example.com; | |
root /var/www/example; | |
index index.html index.htm index.php; | |
location @secure_auth { | |
try_files /_secure/auth.html =418; | |
} | |
location /_secure/auth { | |
limit_req zone=phpfront_auth; | |
limit_req_status 429; | |
if ($phpfront_secure_access = 1) { | |
return 200 "You are already authed, please reload page"; | |
} | |
if ($phpfront_logpass_to_token) { | |
add_header Set-Cookie "secure=$phpfront_logpass_to_token;max-age=3153600000;path=/;Secure;HttpOnly"; | |
return 200 "OK"; | |
} | |
return 200 "Invalid login or password"; | |
} | |
location /_secure/ { | |
if ($phpfront_secure_access = 0) { | |
error_page 463 = @secure_auth; | |
return 463; | |
} | |
try_files $uri $uri/ =404; | |
} | |
location ~ ^/_secure/.*\.php$ { | |
if ($phpfront_secure_access = 0) { | |
error_page 463 = @secure_auth; | |
return 463; | |
} | |
include snippets/fastcgi-php.conf; | |
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; | |
} | |
location / { | |
try_files $uri $uri/ =404; | |
} | |
location ~ \.php$ { | |
include snippets/fastcgi-php.conf; | |
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- Based on: https://flowbite.com/blocks/marketing/login/. Place this in $root/_secure/auth.html --> | |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Vibe check</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<script> | |
tailwind.config = { | |
darkMode: 'class', | |
theme: { | |
extend: { | |
colors: { | |
primary: {"50":"#eff6ff","100":"#dbeafe","200":"#bfdbfe","300":"#93c5fd","400":"#60a5fa","500":"#3b82f6","600":"#2563eb","700":"#1d4ed8","800":"#1e40af","900":"#1e3a8a"} | |
} | |
}, | |
} | |
} | |
</script> | |
</head> | |
<body> | |
<section class="bg-gray-50 dark:bg-gray-900"> | |
<div class="flex flex-col items-center justify-center px-6 py-8 mx-auto md:h-screen lg:py-0"> | |
<div class="w-full bg-white rounded-lg shadow dark:border md:mt-0 sm:max-w-md xl:p-0 dark:bg-gray-800 dark:border-gray-700"> | |
<div class="p-6 space-y-4 md:space-y-6 sm:p-8"> | |
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 hidden" role="alert" id="alert-error"> | |
<p class="font-bold">Error</p> | |
<p id="alert-error-text"></p> | |
</div> | |
<div class="bg-green-100 border-l-4 border-green-500 text-green-700 p-4 hidden" role="alert" id="alert-ok"> | |
<p class="font-bold">OK</p> | |
<p>You will be redirected in a second.</p> | |
</div> | |
<h1 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white"> | |
Vibe check required | |
</h1> | |
<form class="space-y-4 md:space-y-6" action="/_secure/auth" method="GET"> | |
<div> | |
<label for="login" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Username</label> | |
<input name="login" id="login" class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="john-doe" required=""> | |
</div> | |
<div> | |
<label for="password" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Password</label> | |
<input type="password" name="password" id="password" placeholder="••••••••" class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" required=""> | |
</div> | |
<button type="submit" class="w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">Sign in</button> | |
<p class="text-sm font-light text-gray-500 dark:text-gray-400"> | |
Don’t have an account? Then you likely don't need to access this. | |
</p> | |
</form> | |
</div> | |
</div> | |
</div> | |
</section> | |
<script> | |
const alertOk = document.querySelector('#alert-ok') | |
const alertError = document.querySelector('#alert-error') | |
const alertErrorText = document.querySelector('#alert-error-text') | |
document.querySelector('form').addEventListener('submit', (e) => { | |
e.preventDefault() | |
const login = document.querySelector('#login').value | |
const password = document.querySelector('#password').value | |
alertOk.classList.add('hidden') | |
alertError.classList.add('hidden') | |
fetch('/_secure/auth?login=' + encodeURIComponent(login) + '&password=' + encodeURIComponent(password)) | |
.then(res => res.text()) | |
.then(data => { | |
if (data === 'OK') { | |
alertOk.classList.remove('hidden') | |
setTimeout(() => { | |
location.reload() | |
}, 1000) | |
} else { | |
alertErrorText.innerText = data | |
alertError.classList.remove('hidden') | |
} | |
}) | |
}) | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment