SuperGeekery: A blog probably of interest only to nerds by John F Morton.

A blog prob­a­bly of inter­est only to nerds by John Morton.

26Feb2010

A Quick Way To Pass­word Pro­tect a Web Page.

Passwords_Scottie

There are a vari­ety of ways to pass­word pro­tect pages online. Per­haps the eas­i­est is to use an .htac­cess file. The rea­son this is the eas­i­est way is because it’s built into the con­trol pan­el at many host­ing com­pa­nies. I use Dreamhost and it’s con­trol pan­el makes it auto­mat­ic. Sweet. If you don’t have that as part of your host­ing pack­age, check out this arti­cle at htm­l­lite for a walk through on do it yourself.

What I don’t like about the .htac­cess method

Example of .htaccess password dialog box

Exam­ple of what htac­cess pass­word pro­tec­tion looks like.

The .htac­cess method is very secure and time-test­ed. Plus, if your host sup­ports it, it’s real­ly easy to set up. The part I don’t like though is the style of log in win­dow. Depend­ing on your brows­er and oper­at­ing sys­tem, you will see the log in win­dow in a vari­ety of ways. All of them feel like sys­tem’ lev­el box­es, usu­al­ly gray box­es that you can’t customize.

There’s also no easy way to logout once you’re logged into a ses­sion with­out shut­ting your brows­er entirely.

There is anoth­er way.

I’m going to show you a tech­nique that is pret­ty easy to set up. You can prob­a­bly even down­load the exam­ple files then sim­ply place a sin­gle line at the top of any page you want pro­tect­ed and call it a day. The login page is also just HTML, so you can style it any way you want.

You’ll notice all the files have the exten­sion of .php, not .html. It also assumes your serv­er is PHP based. PHP is doing the check­ing and val­i­da­tion, so you need to have .php at the end of your files to get them processed as PHP. That means these files won’t work if you’re just view­ing them from your desk­top. They need the web­serv­er to process them. If you want to know more about doing this on your desk­top a WAMP or MAMP is worth look­ing into. (Learn about WAMP and MAMP on Wikipedia.). I use MAMP almost every­day. You can get a free ver­sion from their site. It’s easy to set up and use. You can also just upload them to your serv­er and do your test­ing there. It should work fine.

This isn’t a new tech­nique, but since I’ve been asked how to do this a num­ber of times, I thought I’d share this tech­nique here on SuperGeekery.

The 5 files

If you haven’t already, down­load the .zip archive of the files, but you don’t need to, I’ll go over them below. There are 8 files in the archive, but you only need 5 of them. The oth­er 3 files are an exam­ple of how to use them to pro­tect and style the pages.

  1. login.php — The page that asks for your password.
  2. checkpw.php — This checks to see if the pass­word entered by the user is the same as what you’ve specified.
  3. wrong.php — What else are you going to call a file that when it tells some­one they are wrong.
  4. logout.php — You’ll nev­er see this file on-screen. It just logs a user out.
  5. protect_page.php — This is the mag­ic file. It’s what pro­tects any page you choose.

login.php

The login file below is the basic login page. I’ve got some divs and spans in it that I use to style the page. You can get rid of those if you don’t want them. In the down­load, you can see the style I’ve applied to the page with the file called pwstyle.css. Here’s the login.php file.

<!DOCTYPE HTML>
<html lang="en-US">
<head>
	<meta charset="UTF-8">
	<title>Log in</title>
	<link rel="stylesheet" media="all" href="pwstyle.css" />
</head>
<body>
	<form name="form1" method="post" action="checkpw.php">
		<div id="container">
			<p>
			<span id="pass">Password:</span>
			<span id="formfield"><input name="pw" type="text" id="pw"></span>
			<span class="submitbt"><input type="submit" name="submitbt"></span>
			</p>
		</div>
	</form>
</body>
</html>

You can see it’s just a form with a sub­mit but­ton. The action is to go to checkpw.php” to check the input.

checkpw.php

This file takes the text that the user entered in the login form. The text is stored in a vari­able called $_POST[‘pw’] and it is com­pared to the pass­word which is hard­cod­ed in the page. You can see the pass­word is sword­fish” in the code on line 10.

This is a sim­ple pass­word pro­tec­tion scheme. It’s check­ing again a sin­gle pass­word. You can make it more robust by hav­ing a data­base plus check­ing against a com­bi­na­tion of a name and pass­word, but that’s more com­pli­cat­ed than I’m show­ing here. I used a strip­slash­es com­mand here in case you end up using it with a data­base. (Click here for more info on stripslashes.)

<?php
// pw is the password sent from the form 
$pw=$_POST['pw'];

// the stripslashes is included in case you end up sending this to a database. It's to help prevent hackers from compromising your system.
$pw = stripslashes($pw);

// you can make this much more robust by checking against a database in this file at this point

if($pw == 'swordfish'){
	session_register("pw"); 
	header("location:index.php");
} else {
	header("location:wrong.php");
}
?>

The last bit above is check­ing whether the user’s pass­word and the required pass­word are the same. When the user gets the pass­word right, we reg­is­ter a ses­sion cook­ie called pw use a head­er redi­rect to send the user to the con­tent, index.php. If their pass­word doesn’t match our pass­word, we send them to wrong.php.

index.php

I don’t have any code to share with you yet for the main page, I’ll cov­er how that page is pro­tect­ed near the end of this post. I’ll show you how to pro­tect any page you want at the same time.

wrong.php

This is basi­cal­ly just a page that says, your pass­word is wrong” and has a link back to the login page.

<!DOCTYPE HTML>
	<html lang="en-US">
	<head>
		<meta charset="UTF-8">
		<title>Log in</title>
		<link rel="stylesheet" media="all" href="pwstyle.css" />
	</head>
	<body>
			<div id="container">
				<p>The password was incorrect. <a href="login.php" title="try again">Try again.</a></p>
			</div>
	</body>
	</html>

logout.php

Anoth­er sim­ple page. All it’s basi­cal­ly doing is destroy­ing the ses­sion cook­ie, then send them back to the login page, but you could send them any­where you want­ed to.

<? 
session_start();
session_destroy();
header("location:login.php");
?>	

protect_page.php — the mag­ic page

<? 
session_start();
if(!session_is_registered(pw)){
header("location:login.php");
}
?>

I think of this as the mag­ic page” because mak­ing this code it’s own file makes it easy to quick­ly unpro­tect files. You could sim­ply put this code at the top of any page you want­ed to, but when you embed it, you can sim­ply com­ment out the con­tent with­in one file and make every file you had pro­tect­ed no longer pro­tect­ed all at once. You com­ment it out as follows:

<? 
	/* session_start();
	if(!session_is_registered(pw)){
	header("location:login.php");
	}*/
?>

Pro­tect­ing your index.php

You may be ask­ing your­self why the login.php file wasn’t named index.php since the login page is what peo­ple see first any­way. I do it this way because the real con­tent of your site or direc­to­ry isn’t the login page, it’s the actu­al con­tent, and you may want to unpro­tect your files at some point. If your home­page was at protectedpage.php instead of index.php, you’ll either have to tell peo­ple to vis­it http://​mysite​.com/​p​r​o​t​e​c​t​e​d​p​a​g​e.php, write a new htac­cess file to make that the default page for that direc­to­ry, or change file names and links inside a bunch of pages to make the non-pro­tect­ed scheme work.

Below you’ll see a sam­ple index.php page that has my real’ con­tent in it. It’s pro­tect­ed by start­ing the page with a sim­ple line: <? include(‘protect_page.php’)?>. It’s impor­tant to note that this path assumes every­thing is in the same direc­to­ry. If you’ve got sub­di­rec­to­ries, you may want to adjust the path to the protect_page.php to some­thing like <? include(‘/protect_page.php’)?>. You may also need to adjust paths in the rest of the files to some­thing similar.

<? include('protect_page.php')?>
<!DOCTYPE HTML>
<html lang="en-US">
<link rel="stylesheet" media="all" href="pwstyle.css" />
<head>
	<meta charset="UTF-8">
	<title>This is password protected</title>
</head>
<body>
	<h1>You can only see this with a valid password.</h1>
	<p>There is a <a href="page2.php" title="Another password protected page.">another password protected page.</a> Try visiting page2.php when you have logged out and you will end up at the log in screen again.</p>
	<h2>How do you use this?</h2>
	<ol>
		<li>You can password protect any page by including the include at the top of this index.php page and any other page you want protected by the password.</li>

	<pre>&lt;? include('protect_page.php')?&gt;</pre>
		<li><p>The pages must have a .php, not a .html. PHP is what is checking for the credentials before displaying the page.</p></li>
		<li>To allow a user to log out, include a link to the logout page.</li>
	</ol>	

	<p><a href="logout.php" title="logout">Click here to log out.</a></p>
</body>
</html>

Pro­tect­ing oth­er pages.

As I men­tioned, pro­tect­ing any page is as sim­ple as includ­ing <? include(‘protect_page.php’)?> at the top, but an exam­ple always helps me out, so you can see below how I’ve done that.

<? include('protect_page.php')?>
<!DOCTYPE HTML>
<html lang="en-US">
<link rel="stylesheet" media="all" href="pwstyle.css" />
<head>
	<meta charset="UTF-8">
	<title>A second page</title>
</head>
<body>
	<h1>A Second Protected page</h1>
	<p>This page is also password protected by the include statement at the top of this document.</p>
	<pre>
&lt;? include('protect_page.php')?&gt;
	</pre>
	<p><a href="logout.php" title="logout">Click here to log out.</a></p>
</body>
</html>

That’s it! Go forth and protect.