I have a page I want to password-protect. I've tried doing HTTP authentication, but for some reason it doesn't work on my hosting. Any other quick (and easy) way to do this? Thanks!
-
7Define "doesn't work". – Oliver Charlesworth Nov 06 '10 at 23:32
-
This depends on a lot of things. Is it just one page? Do you need a visitor to stay validated even if they refresh the page? Are you willing to use sessions? – William Linton Nov 06 '10 at 23:33
-
It's just one page, they don't need to stay validated. I'd prefer not to use sessions, unless there's a really simple way to do it without forms and such. – Leticia Meyer Nov 06 '10 at 23:35
10 Answers
Not exactly the most robust password protection here, so please don't use this to protect credit card numbers or something very important.
Simply drop all of the following code into a file called (secure.php), change the user and pass from "admin" to whatever you want. Then right under those lines where it says include("secure.html"), simply replace that with the filename you want them to be able to see.
They will access this page at [YouDomain.com/secure.php] and then the PHP script will internally include the file you want password protected so they won't know the name of that file, and can't later just access it directly bypassing the password prompt.
If you would like to add a further level of protection, I would recommend you take your (secure.html) file outside of your site's root folder [/public_html], and place it on the same level as that directory, so that it is not inside the directory. Then in the PHP script where you are including the file simply use ("../secure.html"). That (../) means go back a directory to find the file. Doing it this way, the only way someone can access the content that's on the (secure.html) page is through the (secure.php) script.
<?php
$user = $_POST['user'];
$pass = $_POST['pass'];
if($user == "admin"
&& $pass == "admin")
{
include("secure.html");
}
else
{
if(isset($_POST))
{?>
<form method="POST" action="secure.php">
User <input type="text" name="user"></input><br/>
Pass <input type="password" name="pass"></input><br/>
<input type="submit" name="submit" value="Go"></input>
</form>
<?}
}
?>
-
4A simple way to make this more secure: instead of storing the password, store the md5 hash. When they try to log in, check `md5($pass)` against the hash. Even better, store the md5 hash in a file outside the public web root. – William Linton Nov 07 '10 at 02:51
-
3You're right about storing the protected page outside the document root, because in your code, anyone could visit `secure.html` and bypass the PHP script (unless you're using `.htaccess` files or something). – William Linton Nov 07 '10 at 03:10
-
3Like willell mentioned, and I'll say again, don't treat this as a secure password script by any means. Just something I typed up in a minute or two that looked like it might fit the bill to very simply require a pass before seeing a page. – JacobN Nov 07 '10 at 06:08
-
1
-
10You can increase the security by adding something like `$a = 1` to your login page and then `if ($a != 1){ exit(); }` to your secure page that you are loading in. This should prevent access that has not gone through the login page. – Ned Hulton Feb 25 '17 at 00:39
-
This is a bit late but I wanted to reply in case anyone else came upon this page and found that the highest reply was a bit off. I have improved upon the system just a tad bit. Note, it is still not amazingly secure but it is an improvement.
First prepare your password salts file:
hash_generate.php:
<?php
$user = "Username"; // please replace with your user
$pass = "Password"; // please replace with your passwd
// two ; was missing
$useroptions = ['cost' => 8,];
$userhash = password_hash($user, PASSWORD_BCRYPT, $useroptions);
$pwoptions = ['cost' => 8,];
$passhash = password_hash($pass, PASSWORD_BCRYPT, $pwoptions);
echo $userhash;
echo "<br />";
echo $passhash;
?>
Take your output $userhash
and $passhash
and put them in two text files: user.txt and pass.txt, respectively. Others have suggested putting these text files away above public_html, this is a good idea but I just used .htaccess and stored them in a folder called "stuff"
.htaccess
deny from all
Now no one can peek into the hash. Next up is your index.php:
index.php:
<?php
$user = ""; //prevent the "no index" error from $_POST
$pass = "";
if (isset($_POST['user'])) { // check for them and set them so
$user = $_POST['user'];
}
if (isset($_POST['pass'])) { // so that they don't return errors
$pass = $_POST['pass'];
}
$useroptions = ['cost' => 8,]; // all up to you
$pwoptions = ['cost' => 8,]; // all up to you
$userhash = password_hash($user, PASSWORD_BCRYPT, $useroptions); // hash entered user
$passhash = password_hash($pass, PASSWORD_BCRYPT, $pwoptions); // hash entered pw
$hasheduser = file_get_contents("stuff/user.txt"); // this is our stored user
$hashedpass = file_get_contents("stuff/pass.txt"); // and our stored password
if ((password_verify($user, $hasheduser)) && (password_verify($pass,$hashedpass))) {
// the password verify is how we actually login here
// the $userhash and $passhash are the hashed user-entered credentials
// password verify now compares our stored user and pw with entered user and pw
include "pass-protected.php";
} else {
// if it was invalid it'll just display the form, if there was never a $_POST
// then it'll also display the form. that's why I set $user to "" instead of a $_POST
// this is the right place for comments, not inside html
?>
<form method="POST" action="index.php">
User <input type="text" name="user"></input><br/>
Pass <input type="password" name="pass"></input><br/>
<input type="submit" name="submit" value="Go"></input>
</form>
<?php
}
-
This is very Good solution especially when you are saving hashes of the password instead of plain text! now consider if some one got access to your files, he/she will not looking for the real passwords but rather he will take the password protected page.So this solution adds nothing to password protected page but its very good for saving password in database. – Akam Jan 12 '20 at 11:23
-
why do you evaluate $userhash and $passhash in index.php? (trying to figure out why this code doesn't work. (password_verify($user, $hasheduser)) && (password_verify($pass,$hashedpass)) always returns false for me. – Berry Tsakala Mar 14 '20 at 18:53
-
2Berry, This is a very old post. It was more of a proof of concept rather than something for production purposes. I would recommend validating data wherever your business logic is stored rather than the display logic – Juan Mar 16 '20 at 02:48
-
@BerryTsakala the conditional sentence always returns false probably because file_get_contents("stuff/pass.txt") is taken also the end of line character, and not just the hash. As Juan said in a previous comment, to store hashes in files is not the best way to use password_verify, but anyway this code is good to understand the way that password_hash and password_verify work. – skotperez Apr 15 '20 at 13:55
<?php
$username = "the_username_here";
$password = "the_password_here";
$nonsense = "supercalifragilisticexpialidocious";
if (isset($_COOKIE['PrivatePageLogin'])) {
if ($_COOKIE['PrivatePageLogin'] == md5($password.$nonsense)) {
?>
<!-- LOGGED IN CONTENT HERE -->
<?php
exit;
} else {
echo "Bad Cookie.";
exit;
}
}
if (isset($_GET['p']) && $_GET['p'] == "login") {
if ($_POST['user'] != $username) {
echo "Sorry, that username does not match.";
exit;
} else if ($_POST['keypass'] != $password) {
echo "Sorry, that password does not match.";
exit;
} else if ($_POST['user'] == $username && $_POST['keypass'] == $password) {
setcookie('PrivatePageLogin', md5($_POST['keypass'].$nonsense));
header("Location: $_SERVER[PHP_SELF]");
} else {
echo "Sorry, you could not be logged in at this time.";
}
}
?>
And the login form on the page...
(On the same page, right below the above^ posted code)
<form action="<?php echo $_SERVER['PHP_SELF']; ?>?p=login" method="post">
<label><input type="text" name="user" id="user" /> Name</label><br />
<label><input type="password" name="keypass" id="keypass" /> Password</label><br />
<input type="submit" id="submit" value="Login" />
</form>

- 792
- 2
- 19
- 39
-
4Using md5 to hash passwords is a bad idea. Consider using [crypt](http://php.net/crypt) or [password_hash](http://php.net/password-hash) (in PHP >= 5.5.0) or [password_compat](https://github.com/ircmaxell/password_compat) (in PHP >= 5.3.7) instead. – Sherif Feb 24 '14 at 22:46
-
Never hash passwords with MD5, it is easily crackable. I'd recommend using password_hash. – ethry Jun 25 '22 at 00:10
Here's a very simple way. Create two files:
protect-this.php
<?php
/* Your password */
$password = 'MYPASS';
if (empty($_COOKIE['password']) || $_COOKIE['password'] !== $password) {
// Password not set or incorrect. Send to login.php.
header('Location: login.php');
exit;
}
?>
login.php:
<?php
/* Your password */
$password = 'MYPASS';
/* Redirects here after login */
$redirect_after_login = 'index.php';
/* Will not ask password again for */
$remember_password = strtotime('+30 days'); // 30 days
if (isset($_POST['password']) && $_POST['password'] == $password) {
setcookie("password", $password, $remember_password);
header('Location: ' . $redirect_after_login);
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Password protected</title>
</head>
<body>
<div style="text-align:center;margin-top:50px;">
You must enter the password to view this content.
<form method="POST">
<input type="text" name="password">
</form>
</div>
</body>
</html>
Then require protect-this.php on the TOP of the files you want to protect:
// Password protect this content
require_once('protect-this.php');
Example result:
After filling the correct password, user is taken to index.php. The password is stored for 30 days.
PS: It's not focused to be secure, but to be pratical. A hacker can brute-force this. Use it to keep normal users away. Don't use it to protect sensitive information.

- 15,821
- 7
- 92
- 86
-
1I have made password protecting code here: https://github.com/henry7720/Verification-Page no need for 30 day cookies! – Henry7720 Jul 08 '18 at 03:22
-
The text box remembers what was typed in there so when you put your mouse back in there it shows the word that was typed in earlier. ?! – user2568374 Aug 04 '18 at 02:25
-
3Do **not** use a user generated password with this method. Users tend to reuse passowords an storing it in plain text as a cookie may cause the password to be available to other sources. – Neuron Jan 11 '19 at 09:25
-
@Henry7720, thanks for that project, it is fantastic! It should be the accepted answer. – Shōgun8 Jan 16 '21 at 09:23
-
I would personally use $_SESSION[] instead so it's not accessible by other pages. This makes it reset after a browser restart though. – ethry Jun 25 '22 at 00:04
I would simply look for a $_GET
variable and redirect the user if it's not correct.
<?php
$pass = $_GET['pass'];
if($pass != 'my-secret-password') {
header('Location: http://www.staggeringbeauty.com/');
}
?>
Now, if this page is located at say: http://example.com/secrets/files.php
You can now access it with: http://example.com/secrets/files.php?pass=my-secret-password
Keep in mind that this isn't the most efficient or secure way, but nonetheless it is a easy and fast way. (Also, I know my answer is outdated but someone else looking at this question may find it valuable)

- 271
- 2
- 11
A simple way to protect a file with no requirement for a separate login page - just add this to the top of the page:
Change secretuser and secretpassword to your user/password.
$user = $_POST['user'];
$pass = $_POST['pass'];
if(!($user == "secretuser" && $pass == "secretpassword"))
{
echo '<html><body><form method="POST" action="'.$_SERVER['REQUEST_URI'].'">
Username: <input type="text" name="user"></input><br/>
Password: <input type="password" name="pass"></input><br/>
<input type="submit" name="submit" value="Login"></input>
</form></body></html>';
exit();
}

- 4,279
- 1
- 26
- 18
-
-
I like this option if all you need is something very simple to keep less technical people from seeing a certain page. – Kabengwa Patrick Sep 14 '22 at 20:36
Some easy ways:
Use Apache's digest authorization.
Use lighttpd's digest authorization.
Use php's header digest authorization.
If you want you can also make it so only certain ip addresses can login.. :) really easy with lighttpd
Update: I will post some examples soon, so don't vote down for no examples, i just need to get some down for this answer.
If you want to use sessions the following is the best way to go:
# admin.php
session_start();
if(!$_SESSION["AUTH"])
require_once "login.php";
# Do stuff, we are logged in..
# login.php
session_start();
if($_REQUEST["username"] == "user" && $_REQUEST["password"] == "pass")
$_SESSION["AUTH"] = true;
else $_SESSION["AUTH"] = false; # This logs you out if you visit this login script page without login details.
if($_SESSION["AUTH"])
require_once "admin.php";
This method does not contain the examples for above but you seamed interested in this method. The other method examples are still to come, I have not got enough time to get it for apache or lighttpd settings and the php header auth: http://php.net/manual/en/features.http-auth.php Will do.

- 802
- 2
- 11
- 26
</html>
<head>
<title>Nick Benvenuti</title>
<link rel="icon" href="img/xicon.jpg" type="image/x-icon/">
<link rel="stylesheet" href="CSS/main.css">
<link rel="stylesheet" href="CSS/normalize.css">
<script src="JS/jquery-1.12.0.min.js" type="text/javascript"></script>
</head>
<body>
<div id="phplogger">
<script type="text/javascript">
function tester() {
window.location.href="admin.php";
}
function phpshower() {
document.getElementById("phplogger").classList.toggle('shower');
document.getElementById("phplogger").classList.remove('hider');
}
function phphider() {
document.getElementById("phplogger").classList.toggle('hider');
document.getElementById("phplogger").classList.remove('shower');
}
</script>
<?php
//if "login" variable is filled out, send email
if (isset($_REQUEST['login'])) {
//Login info
$passbox = $_REQUEST['login'];
$password = 'blahblahyoudontneedtoknowmypassword';
//Login
if($passbox == $password) {
//Login response
echo "<script text/javascript> phphider(); </script>";
}
}
?>
<div align="center" margin-top="50px">
<h1>Administrative Access Only</h1>
<h2>Log In:</h2>
<form method="post">
Password: <input name="login" type="text" /><br />
<input type="submit" value="Login" id="submit-button" />
</form>
</div>
</div>
<div align="center">
<p>Welcome to the developers and admins page!</p>
</div>
</body>
</html>
Basically what I did here is make a page all in one php file where when you enter the password if its right it will hide the password screen and bring the stuff that protected forward. and then heres the css which is a crucial part because it makes the classes that hide and show the different parts of the page.
/*PHP CONTENT STARTS HERE*/
.hider {
visibility:hidden;
display:none;
}
.shower {
visibility:visible;
}
#phplogger {
background-color:#333;
color:blue;
position:absolute;
height:100%;
width:100%;
margin:0;
top:0;
bottom:0;
}
/*PHP CONTENT ENDS HERE*/

- 31
- 1
This stores the password in history after login!
You can specify a password in your php code so only users that have the secret url can access:
mywebsite.com/private.php?pass=secret
in your login-protected file:
<?php
if(isset($_GET["pass"]) && $_GET["pass"]=="secret"){
//put your code here
}
else{
echo "you're not allowed to access this page";
}
?>

- 441
- 2
- 15
-
This shows the password in history after login! Use $_POST and a form if you want it to be secure! Also, I'd personally use `die()` in the error instead of echo so it blocks anything else from rendering! – ethry Jun 25 '22 at 00:06
Even in 2023, I find myself writing small PHP scripts for debug logging and other testing tasks that I'd rather keep behind some sort of protection, so here's a login script that will let you do all that. It's on GitHub at https://github.com/Mugane/simple-php-auth
<?php
/*
Login system in a single php file.
Tabs, obviously; Configurable editors exist for those with spacing hangups.
© 2023 Peter Kionga-Kamau. MIT License with this comment block left intact.
https://github.com/Mugane/simple-php-auth
*/
// ----------------- Begin Login Section (add protected content after this section) -----------------
@session_start();
// --- start modifiable variables: ---
// $credentials contains unsalted hash for the login "admin" and "password" (replace with your hashed credentials):
// Generate a hash in bash: echo $(echo -n "texttohash" | sha256sum | cut -d " " -f1)
$credentials = array('8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918' => '5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8');
$salt = ''; // add random string here to salt your password hashes (vaguely more secure)
$max_logins = 5; // maximum number of failed login attempts before ban
$ban_time = 24; // ban hours
$time_out = 900; // number of seconds before session timeout (since last active)
$max = 86400; // maximum length of login (even with activity)
// --- end modifiable variables ---
$message = ''; // placeholder for login error/status messages
// If you don't want to use the cookie/phpsessionid, then replace that with some unique string.
// It is only used to provide a pseudo-namespace for the session login details (unique value per user/session):
if(!isset($_COOKIE['PHPSESSID'])) { // check that we can actually use the cookie as the id for authorization
!isset($_SESSION['cookie_try_count'])? $_SESSION['cookie_try_count'] = 1 : $_SESSION['cookie_try_count']++;
if($_SESSION['cookie_try_count'] > 1) { header('HTTP/1.0 418 I\'m a teapot'); exit('<h1>418 I\'m a Teapot</h1>Cookies are required in order to complete this service.'); }
else { header('location: '.$_SERVER['REQUEST_URI']); exit; } // Retry once
}
if(@$_SESSION[$_COOKIE['PHPSESSID']]['auth']['ban_time'] && $_SESSION[$_COOKIE['PHPSESSID']]['auth']['ban_time'] > time()) exit; // this is not very secure
if(isset($_GET["logout"])) LOGGED_IN(0); // log out
if(isset($_REQUEST["login"])) LOG_IN(@$_POST['login'],@$_POST['password']); // log in
if(!LOGGED_IN($time_out, $max)) SHOW_LOGIN();
function LOG_IN($u,$p) {
global $credentials,$max_logins,$ban_time;
unset($_SESSION[$_COOKIE['PHPSESSID']]['auth']['fail_count']);
if(isset($credentials[hash('SHA256',$salt.trim($u))]) && @$credentials[hash('SHA256',$salt.trim($u))] == hash('SHA256',$salt.trim($p))) { // good login
$_SESSION[$_COOKIE['PHPSESSID']]['auth']['last_seen'] = time();
$_SESSION[$_COOKIE['PHPSESSID']]['auth']['login_time'] = time();
$_SESSION[$_COOKIE['PHPSESSID']]['auth']['login'] = trim($u);
unset($_SESSION[$_COOKIE['PHPSESSID']]['auth']['fail_count'], $_SESSION[$_COOKIE['PHPSESSID']]['auth']['message']);
return true;
} // otherwise invalid login, check # attempts/ban:
if(!isset($_SESSION[$_COOKIE['PHPSESSID']]['auth']['fail_count'])) $_SESSION[$_COOKIE['PHPSESSID']]['auth']['fail_count'] = 0;
if(++$_SESSION[$_COOKIE['PHPSESSID']]['auth']['fail_count'] < $max_logins) $_SESSION[$_COOKIE['PHPSESSID']]['auth']['message'] = "Invalid login! Remaining opportunities: ".($max_logins - $_SESSION[$_COOKIE['PHPSESSID']]['auth']['fail_count']).'/'.$max_logins;
else $_SESSION[$_COOKIE['PHPSESSID']]['auth']['ban_time'] = time() + $ban_time * 3600;
SHOW_LOGIN();
}
function SHOW_LOGIN() {
exit ('<html><head><style class="text/css">
body { margin: 0; display: flex; background: linear-gradient(to right, rgba(117,189,209,0.5) 0%, rgba(193,234,191,0.7) 100%), linear-gradient(to bottom, rgba(147,206,222,0) 0%, rgba(117,189,209,1) 41%, rgba(73,165,191,0.6) 100%); }
form { display: flexbox; margin: auto auto; vertical-align: middle; padding: 20px 30px; border-radius:10px; background: rgba(255,255,255,0.75); text-align: right; filter: drop-shadow(15px 10px 6px rgba(0,40,40,0.2)); }
p,input { display: block; font-family: sans-serif; margin: 0 auto; }
input { margin: 5px 0px; padding: 5px 8px; }
input[type=text],input[type=password],input[type=submit] { border: 1px solid rgba(0,0,0,0.4); width: 100%; }
p,input[type=submit] { color: rgba(0,0,0,0.7); width: auto; }
input[type=submit] { margin-left: auto; margin-right: 0; padding: 5px 25px; }
</style></head>
<body><form method="POST" name="login">
<p>'.$_SESSION[$_COOKIE['PHPSESSID']]['auth']['message'].'</p>
<input type="hidden" name="login" value="login" /><input type="text" name="login" />
<input type="password" name="password" /><input type="submit" value="Log in..." />
</form></body></html>');
}
function LOGGED_IN($time_out=180, $max=86400) {
if(@$_SESSION[$_COOKIE['PHPSESSID']]['auth']['login_time'] > 9999999 &&
time() - @$_SESSION[$_COOKIE['PHPSESSID']]['auth']['last_seen'] < $time_out &&
time() - @$_SESSION[$_COOKIE['PHPSESSID']]['auth']['login_time'] < $max ) {
$_SESSION[$_COOKIE['PHPSESSID']]['auth']['last_seen'] = time();
return true;
} else {
if(!isset($_SESSION[$_COOKIE['PHPSESSID']]['auth']['login_time'])) $_SESSION[$_COOKIE['PHPSESSID']]['auth']['message'] = 'You need to log in to access this resource.'; // new login
else if($timeout == 0) $_SESSION[$_COOKIE['PHPSESSID']]['auth']['message'] = 'You have been logged out successfully.'; // log out
else $_SESSION[$_COOKIE['PHPSESSID']]['auth']['message'] = 'Session expired. Please log in again.'; // time out
$_SESSION[$_COOKIE['PHPSESSID']]['auth']['url'] = $_SERVER['REQUEST_URI'];
}
unset($_SESSION[$_COOKIE['PHPSESSID']]['auth']['last_seen'], $_SESSION[$_COOKIE['PHPSESSID']]['auth']['login_time']);
if($time_out == 0) { header('location: '.$_SERVER['PHP_SELF']); exit; }
return false;
}
// ----------------- End Login Section (add protected content after this line) -----------------
echo '<h4>This content is protected.</h4><a href="?logout">log out...</a>';
?>

- 6,504
- 2
- 17
- 13