Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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;
}
@SABTECH

This comment has been minimized.

Copy link

@SABTECH SABTECH commented Aug 12, 2018

hello, what is the default password sir?

@SABTECH

This comment has been minimized.

Copy link

@SABTECH SABTECH commented Aug 12, 2018

Sorry ,i have seen it >>>Good job

@kjagannathreddy

This comment has been minimized.

Copy link

@kjagannathreddy kjagannathreddy commented Dec 15, 2018

what is the password and it displaying error, undefined index password

@SABTECH

This comment has been minimized.

Copy link

@SABTECH SABTECH commented Jan 20, 2019

the password is my_password

@DanielNielsenDK

This comment has been minimized.

Copy link

@DanielNielsenDK DanielNielsenDK commented Jan 29, 2019

Why do I get this error. When entering the password correctly, it redirect it to the protected page. But with ":80" after the domain name.
Example: https://webpage.com/protected-page.php -> When entering the password ->https://webpage.com:80/protected-page.php

@trainoasis

This comment has been minimized.

Copy link

@trainoasis trainoasis commented Mar 27, 2019

You should use isset() for $_POST and other vars...

@javamel

This comment has been minimized.

Copy link

@javamel javamel commented Apr 12, 2019

Hi there. Thanks for this great code. How could I create a button to end the session in order to close access to the protected page ? Thanks.

@dexcuit

This comment has been minimized.

Copy link

@dexcuit dexcuit commented May 31, 2020

always get error

Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at /srv/disk6/1363528/www/myhomedecor.c1.biz/go/css.php:23) in /srv/disk6/1363528/www/myhomedecor.c1.biz/go/protect.php on line 14

any help please

@eric1234

This comment has been minimized.

Copy link
Owner Author

@eric1234 eric1234 commented Jun 2, 2020

@dexcuit - If you are getting that error that means you are sending content prior to session_start. session_start sends a HTTP Header to set the session cookie. If you have already sent content then you cannot call session_start as that sends a HTTP header which much happen before page conent.

@dexcuit

This comment has been minimized.

Copy link

@dexcuit dexcuit commented Jun 2, 2020

eric1234 - your answer make me cry
but thank you any way

@erdengurkan

This comment has been minimized.

Copy link

@erdengurkan erdengurkan commented Jul 1, 2020

@eric1234 Thanks this works great for single page. I'm trying to use for multiple pages under same directory. Ive added below code on every php page on the same directory.

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

It works but asks for password for every page.

Is it possible to share the session with other .php pages within the directory without reentering the password for each page ?

Many thanks in advance!

@eric1234

This comment has been minimized.

Copy link
Owner Author

@eric1234 eric1234 commented Jul 3, 2020

@erdengurkan - Yes, that is what the "scope" parameter is for. If every page has the same scope they will share the same session key.

@erdengurkan

This comment has been minimized.

Copy link

@erdengurkan erdengurkan commented Jul 3, 2020

@eric1234 Thanks a lot for your reply, I've been researching about setting scope but couldn't make it work yet but thanks a lot for showing a direction I will research further

@Pan-dodo

This comment has been minimized.

Copy link

@Pan-dodo Pan-dodo commented Nov 28, 2020

Exactly what I have been looking for. Great code. Thank you very much.

@alexnathanson

This comment has been minimized.

Copy link

@alexnathanson alexnathanson commented Dec 7, 2020

Great code! On line 19 why do you use redirect(current_url()); but line 23 just uses return? Also, is it necessary to separate the HTML form from the PHP? Thanks!

@Baljeet21

This comment has been minimized.

Copy link

@Baljeet21 Baljeet21 commented Dec 10, 2020

Is there any possibility of logging out?

@eric1234

This comment has been minimized.

Copy link
Owner Author

@eric1234 eric1234 commented Dec 10, 2020

@alexnathanson - With regard to redirect vs return, either could work and using return would obviously simplify the code as you then don't need the redirect and current_url methods. But when the page is rendered it is in response to a POST request which can cause user confusion if they hit the refresh for example as it will ask them if they want to re-submit the form. By doing a redirect we turn it back into a GET request as they originally requested which results in a slightly cleaner experience for the user. Yes, you could put the form inline vs as a separate file. I just try to separate code logic from markup so having them as separate files makes it a bit cleaner as the form can then be designed and styled separate from the authentication logic.

@Baljeet21 - To logout you would need to delete the session variable. Some sort of button to signal to the script to do this delete.

@Baljeet21

This comment has been minimized.

Copy link

@Baljeet21 Baljeet21 commented Dec 13, 2020

Thank you. I used this method from stackoverflow: https://stackoverflow.com/questions/37548496/using-onclick-to-destroy-session and everything works perfectly

@Ol-manGrunge

This comment has been minimized.

Copy link

@Ol-manGrunge Ol-manGrunge commented Jan 10, 2021

I need to protect one file and one folder in my php based script. I am not a developer and have no training in PHP. Would it be possible to talk me through this?

@Ol-manGrunge

This comment has been minimized.

Copy link

@Ol-manGrunge Ol-manGrunge commented Jan 16, 2021

Further to the above post, I would be happy to pay for this service.

@eric1234

This comment has been minimized.

Copy link
Owner Author

@eric1234 eric1234 commented Jan 17, 2021

I would suggest reaching out to a local PHP user's group. You should be able to find a contractors that could help you with this.

@Ol-manGrunge

This comment has been minimized.

Copy link

@Ol-manGrunge Ol-manGrunge commented Jan 19, 2021

Thank's Eric.

@duanedoogan

This comment has been minimized.

Copy link

@duanedoogan duanedoogan commented Feb 3, 2021

This works great, been using it, thanks so much, however on two occasions now I've found that without any action that at some point it accepts everything in the password input except the actual password. Has anybody else seen this or any guidance as to why it may be happening?

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