I am having troubles with a PHP login script which checks if you A.) Have registered then B.) Have you clicked the activation link (this is called active in my database)
function login($email, $password, $mysqli, $active) {
// Using prepared statements means that SQL injection is not possible.
if ($stmt = $mysqli->prepare("SELECT id, username, password, hash, active
FROM members
WHERE email = ? LIMIT 1")) {
$stmt->bind_param('s', $email); // Bind "$email" to parameter.
$stmt->execute(); // Execute the prepared query.
$stmt->store_result();
// get variables from result.
$stmt->bind_result($user_id, $username, $db_password, $salt, $active);
$stmt->fetch();
// hash the password with the unique salt.
$password = hash('sha512', $password . $salt);
if ($stmt->num_rows == 1) {
// If the user exists we check if the account is locked
// from too many login attempts
if (checkbrute($user_id, $mysqli) == true) {
// Account is locked
// Send an email to user saying their account is locked
return false;
} else {
// Check if the password in the database matches
// the password the user submitted.
if ($db_password == $password) {
// Password is correct!
// Get the user-agent string of the user.
$user_browser = $_SERVER['HTTP_USER_AGENT'];
// XSS protection as we might print this value
$user_id = preg_replace("/[^0-9]+/", "", $user_id);
$_SESSION['user_id'] = $user_id;
// XSS protection as we might print this value
$username = preg_replace("/[^a-zA-Z0-9_\-]+/", "", $username);
$_SESSION['username'] = $username;
$_SESSION['login_string'] = hash('sha512', $password . $user_browser);
if ($actve != 1){
return false;
header("location ../error.php?err=Account not activated");
exit();
}else{
return true;
header("location ../index.php");
exit();
}
// Login successful.
return true;
} else {
// Password is not correct
// We record this attempt in the database
$now = time();
if (!$mysqli->query("INSERT INTO login_attempts(user_id, time)
VALUES ('$user_id', '$now')")) {
header("Location: ../error.php?err=Database error: login_attempts");
exit();
}
return false;
}
}
} else {
// No user exists.
return false;
}
} else {
// Could not create a prepared statement
header("Location: ../error.php?err=Database error: cannot prepare statement");
exit();
}
}
function checkbrute($user_id, $mysqli) {
// Get timestamp of current time
$now = time();
// All login attempts are counted from the past 2 hours.
$valid_attempts = $now - (2 * 60 * 60);
if ($stmt = $mysqli->prepare("SELECT time
FROM login_attempts
WHERE user_id = ? AND time > '$valid_attempts'")) {
$stmt->bind_param('i', $user_id);
// Execute the prepared query.
$stmt->execute();
$stmt->store_result();
// If there have been more than 5 failed logins
if ($stmt->num_rows > 5) {
return true;
} else {
return false;
}
} else {
// Could not create a prepared statement
header("Location: ../error.php?err=Database error: cannot prepare statement");
exit();
}
}
yes, I know I am using a template from wikihow. But somewhere in the code even if I set active to 0 or 1 in MySQL it logs you in whatever the value is but has an error msg account not activated. I do not know if there is a return true/false statement missing and I have been troubleshooting for days with no avail.
Without seeing how the login method is used it's hard to know for sure, but based on what you have shared the next thing I would try would be:
correct the typo if ($actve != 1){
Move the three calls that set username
user_id
and login_string
on the $_SESSION
in to the else
block so that they only get set in the case of the password matching AND the $active
variable being 1.
See what happens then.