Skip to content

Instantly share code, notes, and snippets.

@eric1234
Last active March 27, 2024 07:15
Show Gist options
  • Star 35 You must be signed in to star a gist
  • Fork 14 You must be signed in to fork a gist
  • Save eric1234/4692807 to your computer and use it in GitHub Desktop.
Save eric1234/4692807 to your computer and use it in GitHub Desktop.
Protect page with simple password

Purpose

Unauthorized access to a PHP page prompts the user for a password. Once the password is entered the original page will show.

Features

  • The access is recorded in the session so it only needs to be entered once.
  • It is possible for multiple pages to share the same scope so access to one page grants access to another page.

Usage

Protecting the Page

Add to the top of the page you want to protect:

require_once 'protect.php';
Protect\with('form.php', 'my_password');

Password Request Form

Now we need to provide a page to prompt the user for the password. It can look like anything you want. The only two requirements are:

  • It must POST the form (i.e. action="POST")
  • The password field must be named password

The following is an example form:

<html>
<body>

<form method="POST">
  <?php if( $_SERVER['REQUEST_METHOD'] == 'POST' ) { ?>
    Invalid password
  <?php } ?>
  <p>Enter password for access:</p>
  <input type="password" name="password">
  <button type="submit">Submit</button>
</form>

</body>
</html>

Place this in the form.php file (or whatever the first argument to the with method is).

Shared Scope

If you need to secure multiple pages and want access on one page to grant access on all pages simply provide a third argument to with. The value of this argument can be anything you desire. It just needs to be the same for all pages. You probably also want to make the form and password the same for all pages.

<?php
# https://gist.github.com/4692807
namespace Protect;
# Will protect a page with a simple password. The user will only need
# to input the password once. After that their session will be enough
# to get them in. The optional scope allows access on one page to
# grant access on another page. If not specified then it only grants
# access to the current page.
function with($form, $password, $scope=null) {
if( !$scope ) $scope = current_url();
$session_key = 'password_protect_'.preg_replace('/\W+/', '_', $scope);
session_start();
# Check the POST for access
if( $_POST['password'] == $password ) {
$_SESSION[$session_key] = true;
redirect(current_url());
}
# If user has access then simply return so original page can render.
if( $_SESSION[$session_key] ) return;
require $form;
exit;
}
#### PRIVATE ####
function current_url($script_only=false) {
$protocol = 'http';
$port = ':'.$_SERVER["SERVER_PORT"];
if($_SERVER["HTTPS"] == 'on') $protocol .= 's';
if($protocol == 'http' && $port == ':80') $port = '';
if($protocol == 'https' && $port == ':443') $port = '';
$path = $script_only ? $_SERVER['SCRIPT_NAME'] : $_SERVER['REQUEST_URI'];
return "$protocol://$_SERVER[SERVER_NAME]$port$path";
}
function redirect($url) {
header("Location: $url");
exit;
}
@rrafluap
Copy link

First, thank you St0wy for the tweaks to make this work again!

I have another issue which is that as of PHP 8.1.0 FILTER_SANITIZE_STRING is deprecated. Therefore the flowing line of code now throws a depreciated warning: $recievedPassword = filter_input(INPUT_POST, 'password', FILTER_SANITIZE_STRING);

Does anyone know of a suitable function to replace this?

TIA

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment