Well, I decided to forget setting globals and to set the session/ print error inside the prepared statement file.
I have been thoroughly through both my registration files and login files. I sat down and wrote the logic of both files and what happens and when. I really cannot see what could be the issue. The logic is pretty much the same and I do the same thing regarding the password and selecting the hash string from db etc.
REGISTRATION
Here is my registration action file, do_reg.php:
PHP Code:
<?php
$db;
//FUNCTION WHICH GENERATES A RANDOM STRING. USED IN THE HASHING OF PASSWORDS. RETURNS A RANDOM STRING.
function generate_salt(){
$chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
$length = strlen($chars);
$salt_size = 10;
global $str;
$str = "";
for($i=0;$i<$salt_size;$i++){
$str .= $chars[rand(0,$length-1)];
}
return $str;
}
function prepare_data($data){
$data = htmlentities($data, ENT_QUOTES);
return $data;
}
if (isset($_POST['username'], $_POST['password'], $_POST['email'])) {
$errors = array();
$_POST['username'] = trim($_POST['username']);
$_POST['password'] = trim($_POST['password']);
$_POST['email'] = trim($_POST['email']);
if (empty($_POST['username'])) {
$errors[] = "Username field cannot be empty.";
}
if (empty($_POST['password'])) {
$errors[] = "Password field cannot be empty.";
}
if (empty($_POST['email'])) {
$errors[] = "Email field cannot be empty.";
}
if(empty($errors)){
if(!ctype_alnum($_POST['username'])){
$errors[] = "Your username can only contain alphanumeric characters.";
}
if(!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)){
$errors[] = "You did not enter a valid email address.";
}
if(strlen($_POST['password']) < 5 || strlen($_POST['password']) > 18){
$errors[] = "Your password must be between 6 and 18 characters long.";
}
if(empty($errors)){
require("reg_select.php");
if($result === TRUE){
echo "Sorry, the username and/or email address is already in use.<br />";
echo "<a href='register.php'>Please try again</a>";
exit(0);
}
else{
$db = TRUE;
}
}
else{
$error_string = implode("<br />",$errors);
print($error_string);
print("<br />");
print("<a href='register.php'>Click here to go back to the registration page</a>");
exit(0);
}
}
else{
$error_string = implode("<br />",$errors);
print($error_string);
print("<br />");
print("<a href='register.php'>Click here to go back to the registration page</a>");
exit(0);
}
}
if($db != NULL){
$_POST['username'] = prepare_data($_POST['username']);
$_POST['password'] = prepare_data($_POST['password']);
$_POST['email'] = prepare_data($_POST['email']);
//generate hashed password.
$hash = generate_salt();
$_POST['password'] = sha1($hash.$_POST['password'].$hash);//users password
require("reg_insert.php");
}
$con->close();
?>
As you can see, my reg_select.php is used just to see if any users/email are already registered........don't need to see that one.....
Here is my reg_insert.php - which as you can guess, registers the user:
PHP Code:
<?php
$conn = new mysqli("localhost","root","","demo_central");
$stmt = $conn->prepare("INSERT INTO members (username,password,email,join_date,hash) VALUES (?,?,?,?,?)");
$user = mysqli_real_escape_string($conn,$_POST['username']);
$pass = mysqli_real_escape_string($conn,$_POST['password']);
$email = mysqli_real_escape_string($conn,$_POST['email']);
$time = time();
$hash;
$stmt->bind_param("sssis",$user,$pass,$email,$time,$hash);
$stmt->execute();
$n_rows = $stmt->num_rows;
if($n_rows >= 1){
$in_result = TRUE;
}
else{
$in_result = FALSE;
}
if($in_result === TRUE){
//write email after data is successully inserted.
$to = $_POST['email'];
$subject = "Thank you for registering at Demo-Central!";
$message = "Welcome ".$_POST['username']."<br />\n<br />\n";
$message .= "Thank you for registering at Demo-Central.<br />\n";
$message .= "You can now enjoy the ability to upload your own demos to show off and also <br />\n";
$message .= "editing your own profile to make yourself unique. Below you will find your login details:<br />\n<br />\n";
$message .= "Your username is:".$_POST['username']."<br />\n";
$message .= "Your password is:".$_POST['password']."<br />\n<br />\n";
$message .= "Please save this email to ensure you can retrieve your username or password should you forget it.<br />\n<br />\n";
$message .= "We look forward to watching you.<br />\n<br />\n";
$message .= "Kind regards,<br />\n<br />\n";
$message .= "Demo-Central Administrator.";
$headers = array();
$headers[] = "MIME-Version: 1.0";
$headers[] = "Content-type: text/html; charset=iso-8859-1";
$headers[] = "From: Demo-Central Admin <admin@demo-central.com>";
$headers[] = "Bcc: JJ Chong <bcc@domain2.com>";
$headers[] = "Reply-To: Recipient Name <receiver@domain3.com>";
$headers[] = "Subject: {$message}";
$headers[] = "X-Mailer: PHP/".phpversion();
if(mail($to,$subject,$message, implode("\r\n",$headers))){
echo "You have successfully registered! You will be contacted shortly with your login details.<br />";
echo "Please follow the <a href='login.php'>link</a> to the login page.";
exit(0);
}
else{
echo "You have successfully registered but there was an error sending your email.<br />";
echo "You are still able to login. Please contact the site administrator at flipmodeskwaud@hotmail.co.uk to report the problem.<br />";
echo "Follow the link to the <a href='login.php'>login</a> page.";
exit(0);
}
}
else{
echo "There was an internal error with your registration.<br />";
echo "Please contact the administrator at flipmodeskwaud@hotmail.co.uk and include the error shown. Thank you.<br />";
echo "Click <a href='index.php'>here</a> to go to the homepage.";
exit(0);
}
$stmt->close();
$conn->close();
?>
LOGIN
do_login.php:
PHP Code:
<?php
//FUNCTION WHICH PREPARES THE USER INPUT FOR DATABASE INSERTION. RETURNS 'CLEANED' DATA.
function prepare_data($data){
$data = htmlentities($data, ENT_QUOTES);
return $data;
}
$db;
if(isset($_POST['username'], $_POST['password'])){
$errors = array();
$_POST['username'] = trim($_POST['username']);
$_POST['password'] = trim($_POST['password']);
if(empty($_POST['username'])){
$errors[] = "Username field cannot be empty.";
}
if(empty($_POST['password'])){
$errors[] = "Password field cannot be empty.";
}
if(empty($errors)){
$db = TRUE;
}
else{
$error_string = implode("<br />",$errors);
print($error_string);
print("<br />s");
print("<a href='login.php'>Please try again</a>");
exit(0);
}
}
if($db != NULL){
$_POST['username'] = prepare_data($_POST['username']);
$_POST['password'] = prepare_data($_POST['password']);
$con = new mysqli("localhost","root","","demo_central");
$stmt = $con->prepare("SELECT hash FROM members WHERE username=?");
$stmt->bind_param("s",$_POST['username']);
$stmt->bind_result($hash);
$stmt->execute();
$stmt->store_result();
$a_rows = $stmt->affected_rows;
$n_rows = $stmt->num_rows;
$stmt->fetch();
$_POST['password'] = sha1($hash.$_POST['password'].$hash);
if($a_rows == 1 AND $n_rows == 1){
require("login_select.php");
}
else{
echo "That username does not exist.<br />";
$qry = NULL;
}
if($qry == NULL){
echo "<a href='login.php'>Please try again.</a>";
exit(0);
}
}
?>
login_select.php - which selects a match for user and pass.
PHP Code:
<?php
session_start();
$conn = new mysqli("localhost","root","","demo_central");
$stmt = $conn->prepare("SELECT * FROM members WHERE username=? AND password=?");
$username = mysqli_real_escape_string($conn,$_POST['username']);
$password = mysqli_real_escape_string($conn,$_POST['password']);
$stmt->bind_param("ss",$username,$password);
$stmt->bind_result($id,$user,$pass,$email,$join_date,$hash,$reset);
$stmt->execute();
$stmt->store_result();
$rows = $stmt->affected_rows;
$stmt->fetch();
if($rows == 1){
$_SESSION['username'] = $username;
$_SESSION['password'] = $password;
header("refresh: 5, url=membersarea.php");
echo "You have successfully logged in.<br />";
echo "You will be redirected shortly...";
exit(0);
}
else{
echo "You entered an invalid username and/or password.<br />";
echo "<a href='login.php'>Please try again</a>";
exit(0);
}
$stmt->close();
$conn->close();
?>
As far as I can see, it should work. As I said, it works locally, but when I put it online, it doesn't seem to work the same.
Not sure what this issue could be.
I am wondering if anyone can spot the mistake?
Kind regards,
LC.