PHP Code for Forum Login
Forums are great communication tools for the exchange of ideas, for people teaching others about a specific area of interest, or even for just general social communication. The fact that they are usually so specialized helps get them high up in search results as well as contributing considerably to bodies of knowledge. True, there's a lot of misinformation and putdowns, but this invariably occurs when people communicate. One must learn to take what one learns with a grain of salt.
One of the critical functions on a forum is the Search function. The best searches have relevancy scoring and highlighting. Our forum search code has these. This allows results where the most relevant results are shown first and the search term matches are pointed out to the user quite clearly. The login script below, which is also the registration script, has both captcha functions (for signup) and password hashing. And in addition to this, there are various security precautions on every web page in the app. For the captcha, here's the question that gets asked, and the question is an image so the automatic login spammers cannot read it—but even if they could read it, they'd have to be able to figure out the answer, which few spambots could do.
The code below starts out with JavaScript validation scripts. There are PHP validation scripts as well, for extra security. Note that the password validator allows both alphanumeric and !@#$%^&*()_ characters. This shouldn't be a security issue since the password gets hashed into a 65-character hash for db storage with no dangerous characters in it whatsoever. The hashing algorithm actually creates an even longer hash, but we use only the first 65 characters. The user name is restricted to 6 to 20 letters, numbers and underline, and if the JavaScript validator misses any violations because the user has JavaScript turned off, the PHP validator will catch it. The reason to use JavaScript validators as well as PHP validators on input is that it helps keep the host server from getting overwhelmed. The email validator will allow most any email that uses only alphanumerics, hyphen, underscore, dots and a @. Note that the scripts use
focus() to keep users on an input box until they enter acceptable input, and the PHP validators are even more insistent.
On to the PHP code. As usual, we start with config.php, since without it, the MySQL-based forum would not be viable. You cannot relate to a db without knowing the magic words. The mix() function hashes the password, one character at a time, with md5(), then does a sha512() hash on the result before it gets trimmed down to 65 characters. Then the members table gets created if there is none.
The input data gets POSTed to the PHP, next, along with the captcha question response and the register flag which tells the script the form was submitted. If they're logging in rather than signing up, a login flag will be set and the registration flag will not be and the captcha won't be asked or answered. For signup, if the answer is wrong, the user gets a message and the page reloads, but if s/he got it right, the $L string where the captcha is stored is turned into the word "crapola" which will mean the question was answered right. If the username fails to validate, the user gets a message and the page reloads. If the password fails to validate because it's not 6 to 20 characters, the user gets a message and the page reloads. If the email fails to validate, the user gets a message and the page reloads.
Before the hashing function is run and the data stored in the MySQL table, the user name is checked to see if that name is taken. If it is, the user is told that and asked to try again. The user IP address and the date are stored along with the other data. If the registration was successful, the user gets an email and a message "Thank you for registering." Then s/he's sent to the forum, using a query string with the user name in it. A valid user name will be checked for in each web page of the forum app, and it will be run through a validator that will accept only safe, valid characters before the members table will be queried to see if s/he is legitimate.
This isn't the world's most secure method, but then neither are session or cookie based methods, mostly due to all the security holes each exposes. If you must use sessions, try to improve session security. Like they say on Tizag.com, "Note: If you are not experienced with session programming it is not recommended that you use sessions on a website that requires high-security, as there are security holes that take some advanced techniques to plug." To sum up, neither passing things as query strings nor sessions are very secure, but at least query strings are less complex to deal with. Either method is easy to hack by a decent hacker, but if there's no sensitive data transfer on your site, they're not too likely to bother. The password scripts on our blog app, on the other hand, are very difficult to hack. You'll NEVER see passwords in URL query strings on our sites or on any but the dumbest and least secure sites. We recommend storing passwords only as hashes.
Note that both the HTML forms which solicit the user input use the login page as their action—they send the POSTs to themselves (this login/registration script). Also, the form submit button triggers onsubmit="return validatepassword()" if JavaScript is turned on, running the validators. If it is turned off, the PHP validators will sanitize input anyway—no problem.
Both the login and the registration scripts are on the login page and in the code below, with the main difference being that the latter has the captcha and email inputting, but the former does not.
SAVE THIS PAGE AS: login.php
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
<TITLE>Login</TITLE>
<meta name="description" content="Login Script">
<meta name="keywords" content="Login Script,login,php,javascript, dhtml, DHTML">
<style type="text/css">
BODY {margin-left:0; margin-right:0; margin-top:0;text-align:left}
p, li {font:13px Verdana; color:black;text-align:left}
h1 {font:bold 28px Verdana; color:black;text-align:center}
h2 {font:bold 24px Verdana;text-align:center}
h3 {font:bold 15px Verdana;}
</style>
<script language="javascript">
function validatepassword(){
var ck_password = /^[A-Za-z0-9!@#$%^&*()_]{4,20}$/;
if (document.formpw.upassword.value.search(ck_password)==-1)
{alert("Please only enter letters, numbers and these for the password: !@#$%^&*()_");
document.formpw.upassword.focus();return false}
var ck_username = /^[A-Za-z0-9_]{6,20}$/;
if (document.formpw.username.value.search(ck_username)==-1)
{alert("Please only enter 6 to 20 letters, numbers and underline for the user name.");document.formpw.username.focus();
return false}
var ck_email = /^[A-Za-z0-9-_]+(\.[A-Za-z0-9-_]+)*@([A-Za-z0-9-_]+\.)?([A-Za-z0-9-_]+(\.[A-Za-z]{2,6})(\.[A-Za-z]{2})?)$/;
if (document.formpw.email.value.search(ck_email)==-1)
{alert("That email address is not valid. Try again.");document.formpw.email.focus();return false;}
return true;}
function validatepasswordlogin(){
var ck_password = /^[A-Za-z0-9!@#$%^&*()_]{4,20}$/;
if (document.formlogin.upasswordlogin.value.search(ck_password)==-1)
{alert("Please only enter letters, numbers and these for the password: !@#$%^&*()_");
document.formlogin.upasswordlogin.focus();return false}
var ck_username = /^[A-Za-z0-9_]{6,20}$/;
if (document.formlogin.uname.value.search(ck_username)==-1)
{alert("Please only enter 6 to 20 letters, numbers and underline for the user name.");document.formlogin.uname.focus();
return false}
return true;}
</script>
</head>
<body>
<?php
include_once"config.php";
function mix(){
global $upassword, $c;
$p = str_split($upassword);
foreach ($p as $h){$m .= md5($h);}
$c = hash('sha512',$m);
$c = substr($c, 0, 65);}
$sql = "CREATE TABLE IF NOT EXISTS members (
id int(4) NOT NULL auto_increment,
username varchar(20) NOT NULL,
upassword varchar(65) NOT NULL,
email varchar(65) NOT NULL,
ip varchar(65) NOT NULL,
date varchar(65) NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM AUTO_INCREMENT=1";
// Execute query
mysql_query($sql);
if(isset($_POST['register'])){
$U = $_POST['username'];
$L = $_POST['captcha'];if ($L<>"of"){
echo '<script language="javascript">alert("Please answer question."); window.location = "login.php"; </script>';
}else{$L="crapola";}
$U = strip_tags($U);
if (!preg_match("/[A-Za-z0-9_]{6,20}$/",$U)) {
echo '<script language="javascript">alert("Please enter 6 to 20 letters, numbers and underline for username."); window.location = "login.php"; </script>';}
$upassword = $_POST['upassword'];
if (strlen($upassword)<6 || strlen($upassword)>20) {
echo '<script language="javascript">alert("Please enter 6 to 20 characters for password."); window.location = "login.php"; </script>';}
$email = $_POST['email'];
$email = strip_tags($email);
$email = htmlspecialchars($email, ENT_QUOTES);
if (!preg_match("/([\w\-]+\@[\w\-]+\.[\w\-]+)/",$email)) {
echo '<script language="javascript">alert("That email address is not valid."); window.location = "login.php"; </script>';}
$memip = $_SERVER['REMOTE_ADDR'];
$date = date("d-m-Y");
$checkformembers = mysql_query("SELECT * FROM members WHERE username = '$U'");
if(mysql_num_rows($checkformembers) != 0){echo '<script language="javascript">alert("Username already in use. Please try again.")</script>;';
}else{
mix();
if($L=="crapola"){
$create_member = mysql_query("INSERT INTO members (id, username, upassword, email, ip, date)
VALUES('','$U','$c','$email','$memip','$date')") or die(mysql_error());
$to = $email;
$subject = "Welcome to the Forum!";
$message = "You've successfully registered as Forum member.\n\nYour user name is ".$U.".\n\nYou may now go to the forum and add topics or reply to existing topics.\n\nDon't give your password to anyone, but do save it somewhere safe.\n\nEnjoy the Forum!\n\nRegards,\n\nthe Forum management";
$headers = "From: ".$psbhostemailaddress."\r\nReply-To: ".$email;
$mail_sent = mail($to, $subject, $message, $headers);
echo '<BR><BR><script language="javascript">alert("Thank you for registering.");window.location = "cms-forum.php?username='.$U.'";</script>';}}}
if(isset($_POST['login'])&&isset($_POST['uname'])&&isset($_POST['upasswordlogin'])){
$U = $_POST['uname'];
$P = $_POST['upasswordlogin'];$upassword=$P;mix();
$check_user_data = mysql_query("SELECT * FROM members WHERE username = '$U'") or die(mysql_error());
if(mysql_num_rows($check_user_data) == 0)
{echo '<script language="javascript">alert("This user name does not exist. Please try again.")</script>;';unset($U);unset($P);
}else{
$get_user_data = mysql_fetch_array($check_user_data);
$Z=$get_user_data['upassword'];
if($Z != $c || !isset($_POST['login']))
{echo '<script language="javascript">alert("Username/password pair is invalid. Please try again.")</script>;';unset($U);unset($P);
}else{
echo '<script language="javascript">window.location = "cms-forum.php?username='.$U.'";</script>';}}}
?>
<h1>Login or Sign-up</h1>
<div id='pw' style='position:absolute;top:110px;left:600px;width:350px;border:4px solid blue;background-color:#8aa;'><table border='0' cellspacing=0 cellpadding=6><tr><th style='font-size:24;text-align:center'>Sign Up</th></tr>
<form id='formpw' name="formpw" method="post" action="login.php" onsubmit="return validatepassword()">
<tr><td><label for="User Name"><b>User Name: </b><input type="text" name="username" size="20" maxlength="20" value=""></label> </td></tr>
<tr><td><label for="Password"><b>Password: </b><input type="password" name="upassword" size="20" maxlength="20" value=""></label> </td></tr>
<tr><td><label for="Email"><b>Email: </b><input type="text" name="email" size="25" maxlength="65" value=""></label> </td></tr>
<tr><td><label for="Please answer question"><b>Please answer question: </b><input type="text" name="captcha" size="16" maxlength="16" value=""></label></td></tr>
<tr><td> <IMG SRC="login-question.png" WIDTH=295 HEIGHT=36 BORDER=0></td></tr>
<tr><td><BR>
<input type="submit" value="Submit" name="register">
<input type="reset" value="Reset"></form></td></tr></table>
</div>
<div id='login' style='position:absolute;top:110px;left:100px;width:350px;border:4px solid blue;background-color:#8aa;'><table border='0' cellspacing=0 cellpadding=6><tr><th style='font-size:24;text-align:center'>Login</th></tr>
<form id='formlogin' name="formlogin" method="post" action="login.php" onsubmit="return validatepasswordlogin()">
<tr><td><label for="User Name"><b>User Name: </b><input type="text" name="uname" size="20" maxlength="20" value=""></label> </td></tr>
<tr><td><label for="Password"><b>Password: </b><input type="password" name="upasswordlogin" size="20" maxlength="20" value=""></label> </td></tr>
<tr><td><BR>
<input type="submit" value="Submit" name="login">
<input type="reset" value="Reset"></form></td></tr></table>
</div>
</body>
</html>