PDO with MySQL not working in email activation - php

Okay, so I'm setting up the activation page using $_GET[] from the link the server emails the user.
Here's my activation page.
if (isset($_GET['success']) && $_GET['success'] == false) {
echo 'Your account has been activated, please login to continue.';
} else if (isset($_GET['email'], $_GET['email_code']) === true) {
$email = trim($_GET['email']);
$email_code = trim($_GET['email_code']);
if (email_exists($db, $_GET['email']) == false) {
$errors[] = 'This email address hasn\'t been registered with us.';
} else if (activate($db, $email, $email_code) === false) {
$errors[] = 'We had problems activating your account, please contact an Administrator.';
}
if (empty($errors) === false) {
echo output_errors($errors);
} else {
header('Location: activate.php?success');
exit();
}
} else {
header('Location: index.php');
}
I believe that to be fine, the problem lies within my function activate()
function activate(PDO $db, $email, $email_code) {
$stmt = $db->prepare("SELECT COUNT (`id`) FROM `users` WHERE `email` = :email AND `email_code` = :email_code AND `active` = 0");
$stmt->bindValue(':email', $email);
$stmt->bindValue(':email_code', $email_code);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_OBJ);
return $row ? $row->type : 0;
}
At this moment, I'm just trying to get it to return something, yet it doesn't.
What I really need, is for it to do this.
function activate($email, $email_code) {
$email = mysql_real_escape_string($email);
$email_code = mysql_real_escape_string($email_code);
if (mysql_result(mysql_query("SELECT COUNT(`user_id`) FROM `users` WHERE `email` = '$email' AND `email_code` = '$email_code' AND `active` = 0"), 0) ==1) {
mysql_query("UPDATE `users` SET `active` = 1 WHERE `email` = '$email'");
return true;
} else {
return false;
}
}
But I cannot quite translate it.
Any help would be appreciated, thanks.
I thought I'd add this doesn't return any errors, mainly because I haven't put anything in correctly yet for it to return one.
EDIT:
else if (activate($db, $email, $email_code) === 0) {
$errors[] = 'We had problems activating your account, please contact an Administrator.';
}
Then the function
function activate(PDO $db, $email, $email_code) {
$sql = "SELECT `active`, `email_code` FROM `users` WHERE `email` = '?'";
$stmt = $db->prepare($sql);
$stmt->execute(array($email));
$row = $stmt->fetch();
if ($row && $row['active'] == $email_code && !$row['active'] ) {
$sql = "UPDATE `users` SET `active` = 1 WHERE `email` = '?'";
$stmt = $db->prepare($sql);
$stmt->execute(array($email));
return $stmt->rowCount();
} else {
return 0;
}
}

function activate(PDO $db, $email, $email_code) {
$sql = "SELECT active, email_code FROM users WHERE email = ?";
$stmt = $db->prepare($sql);
$stmt->execute(array($email));
$row = $stmt->fetch();
$if ($row && $row['active'] == $email_code && !$row['active'] )
$sql = "UPDATE users SET active = 1 WHERE email = ?");
$stmt = $db->prepare($sql);
$stmt->execute(array($email));
return $stmt->rowCount();
}
}

Related

Login function only works once

I have the following php functions that process a user logging in. The functions are part of a class User.
/*
* detail() function to get a detail from a database
* exists() function to check if something exists in a database
*/
private function generate($password, $username = null) {
if(is_null($username)) {
$date = '0000-00-00';
} else {
$date = $this->_db->detail('last_active', 'users', 'username', $username);
}
// This is not the real thing but it will do as an example
$salt = md5(strrev($password.$date));
$password = md5($salt.$password.$date).strrev($password);
return $password;
}
public function login($data = array()) {
// Check if the user exists
$username = $data['username'];
if($this->_db->exists('username', 'users', 'username', $username)) {
$password = $this->generate($data['password'], $username);
// If the account is active
if ($this->_db->detail('active', 'users', 'username', $username) === 1) {
$stmt = $this->_db->mysqli->prepare("SELECT `username`, `password` FROM `users` WHERE `username` = ? AND `password` = ? AND `active` = 1");
$stmt->bind_param('ss', $username, $password);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows >= 1) {
// Function to update last_active
if($this->updateLastActive($username)) {
// Function to update password
if($this->updatePassword($username, $this->generate($password, $username))) {
// Set the session
$this->_session->set('user', $this->_db->detail('id', 'users', 'username', $username));
if($this->_session->exists('user')) {
return true;
} else {
echo 'Logging in went wrong';
return false;
}
} else {
echo 'Editing the password went wrong';
return false;
}
} else {
echo 'Editing last active date went wrong';
return false;
}
} else {
echo 'Wrong username and password combination';
return false;
}
} else {
echo 'Account not active';
return false;
}
} else {
echo 'Username doesn\'t exists';
return false;
}
}
private function updateLastActive($username) {
$date = date('Y-m-d');
$stmt = $this->_db->mysqli->prepare("UPDATE `users` SET `last_active` = ? WHERE `username` = ?");
$stmt->bind_param('ss', $date, $username);
$stmt->execute();
if($stmt->affected_rows >= 1) {
return true;
} else {
return false;
}
}
private function updatePassword($username, $password) {
$stmt = $this->_db->mysqli->prepare("UPDATE `users` SET `password` = ? WHERE `username` = ?");
$stmt->bind_param('ss', $password, $username);
$stmt->execute();
if($stmt->affected_rows >= 1) {
return true;
} else {
return false;
}
}
The user can login with no problem when he just registered. But when the user is logged out and than tries to login again it will fail. The part I get an error on is the following:
$stmt = $this->_db->mysqli->prepare("SELECT `username`, `password` FROM `users` WHERE `username` = ? AND `password` = ? AND `active` = 1");
I tried to find out where the script fails with echo on different places in the functions but I couldn't find the error. The reason why the generate() function has $username = null is because the same function is used for registration.
So all functions are working but they only work once so this leaves me that someting in the generate() function is wrong. I always get the message that there is something wrong with the username / password combination
If someone could point me in the right direction I would be very happy.
Thanks in advance
UPDATE
The detail() and exists() functions are part of a class Database.
public function detail($detail, $table, $column, $value) {
if(is_array($detail)) {
$data = array();
foreach($detail as $key) {
$stmt = $this->mysqli->prepare("SELECT `$key` FROM `$table` WHERE `$column` = ?");
if(is_numeric($value)) {
$stmt->bind_param('i', $value);
} else {
$stmt->bind_param('s', $value);
}
$stmt->execute();
$stmt->bind_result($detail);
$stmt->fetch();
$data[] = $detail;
$stmt = null;
}
return $data;
} else {
$stmt = $this->mysqli->prepare("SELECT `$detail` FROM `$table` WHERE `$column` = ?");
if(is_numeric($value)) {
$stmt->bind_param('i', $value);
} else {
$stmt->bind_param('s', $value);
}
$stmt->execute();
$stmt->bind_result($detail);
$stmt->fetch();
return $detail;
}
}
public function exists($detail, $table, $column, $value) {
$stmt = $this->mysqli->prepare("SELECT `$detail` FROM `$table` WHERE `$column` = ?");
switch(is_numeric($value)) {
case true:
$stmt->bind_param('i', $value);
break;
case false:
$stmt->bind_param('s', $value);
break;
}
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows >= 1) {
return true;
} else {
return false;
}
}
Create a hash field in your table, make it long enough to avoid length issue.
md5() is not acceptable now, you should be using better hash function such as password_hash()
Register:
private function register($username, $password) {
//safer than md5() anyway
$hash = password_hash($password, PASSWORD_DEFAULT);
$sql = 'INSERT INTO table_name (`username`, `hash`) VALUES (?, ?);'
$stmt = $this->_db->mysqli->prepare($sql);
$stmt->bind_param('ss', $username, $hash);
$stmt->execute();
if($stmt->affected_rows >= 1) {
return true;
} else {
return false;
}
}
Login :
public function login($username, $password) {
// Check if the user exists
if($this->_db->exists('username', 'users', 'username', $username)) {
// If the account is active
if ($this->_db->detail('active', 'users', 'username', $username) === 1) {
$sql = 'SELECT `username`, `hash` FROM `users` WHERE `username` = ? AND `active` = 1';
$stmt = $this->_db->mysqli->prepare();
$stmt->bind_param('ss', $username, $hash);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows === 1) {
if (password_verify($password, $hash)) {
// Function to update last_active
if($this->updateLastActive($username)) {
echo 'last active updated, Login successful';
return true;
} else {
echo 'Editing last active date went wrong';
return false;
}
} else {
echo 'Wrong username and password combination';
return false;
}
} else {
echo 'Account not active';
return false;
}
} else {
echo 'Username doesn\'t exists';
return false;
}
}
}
Of course you can still use custom salt, for example
$hash = password_hash($password
,PASSWORD_DEFAULT
,array('salt' =>generate()));//generate() returns the salt

Use SQL to check if user exists in database

I'm trying to check a table called members to see if a user exists with it's email and password. I'm able to connect to the database, but for some reason, it jumps all these if statements and echoes 'You have been logged in!' even when I put the wrong email or password? Here is the html and php:
<form action="/login-user" method="POST">
Email: <input type="text" name="login_email"><br>
Password: <input type="password" name="login_password"><br>
<button type="submit">Login</button>
</form>
PHP:
<?php
session_start();
/*error_reporting(0);*/
require 'users/functions/user-functions.php';
require 'users/connect-database.php';
if (empty($_POST) === false) {
$email = mysqli_real_escape_string($connection, $_POST['login_email']);
$password = stripslashes(mysqli_real_escape_string($connection, $_POST['login_password']));
$encrypted_password = md5($password);
if (empty($email)) {
echo 'You need to enter an email<br>';
} else if (empty($password)) {
echo 'You need to enter a password<br>';
} else if(user_exists($connection, $email, $encrypted_password) === false) {
echo 'You don\'t seem to be registered?';
} else if (user_active($connection, $email, $encrypted_password) === false) {
echo 'You haven\'t activated your account!';
} else {
$login = login($connection, $email, $encrypted_password);
if ($login === false) {
echo 'That email/password combination is incorrect';
} else {
$_SESSION['user_id'] = $login;
$_SESSION['logged_in'] = true;
echo 'You have been logged in!';
}
}
/*print_r($errors);*/
} else {
echo 'inputs were empty<br>';
}
require 'users/disconnect-database.php';
?>
Content of the file 'user-functions.php':
<?php
function sanitize($connection, $data) {
return mysqli_real_escape_string($connection, $data);
}
function logged_in() {
return $_SESSION['logged_in'];
}
function user_exists($connection, $email, $password) {
$query = mysqli_num_rows(mysqli_query($connection, "SELECT * FROM members WHERE email = '$email' AND password = '$password'"));
return ($query > 0) ? true : false;
}
function user_active($connection, $email, $password) {
$query = mysqli_query($connection, "SELECT user_id FROM members WHERE email = '$email' AND password = '$password' AND `active` = 1");
return ($query !== false) ? true : false;
}
function return_user_id($connection, $email, $password) {
return mysqli_query($connection, "SELECT user_id FROM members WHERE email = '$email' AND password = '$password'");
}
function login($connection, $email, $password) {
/*$user_id = mysql_result(mysqli_query($connection, "SELECT user_id FROM members WHERE email = '$email' AND password = '$password'"), 0, 'user_id');*/
/*$password = md5($password);*/
$query = mysqli_query($connection, "SELECT user_id FROM members WHERE email = '$email' AND password = '$password'");
/*return (mysqli_query($connection, $query) or die (false));*/
if ($query === false) {
return false;
} else {
return $query;
}
/*return ($query !== false) ? true : false;*/
}
function log_out() {
unset($_SESSION['logged_in']);
session_unset();
session_destroy();
}
?>
If the answer is using mysql_result or mysqli_result, please explain in full detail because even after reading on the manual and W3Schools and everywhere else, I still don't understand how those functions work.
Thanks for any answers, and by the way, I have read all the other posts about this stuff but I didn't find any answers. Thanks.
First of all I would really advise to use a sha for encrypting passwords because md5 is decrypted in no time at all.
for your login function try the following:
<?php
function login($connection, $email, $password) {
$query = mysqli_query($connection, "SELECT `email`, `password` FROM `members` WHERE `email` = '$email' AND `password` = '$password'");
$count = mysqli_num_rows($query); //counting the number of returns
//if the $count = 1 or more return true else return false
if($count >= 1) {
return true;
} else {
return false;
}
}
?>
after the script has returned true you could set a session or do what you need to do with it.
EDIT You need session_start in every file so the best thing to do is include this.
I hope this works I typed it realy fast so there might be some errors in it but please let me know:
<?php
function generate($password) {
$password = hash('sha1', $password);
return $password;
}
function login($connection, $email, $password) {
$password = generate($password);
$query = mysqli_query($connection, "SELECT `email`, `password` FROM `members` WHERE `email` = '$email' AND `password` = '$password'");
$count = mysqli_num_rows($query); //counting the number of returns
//if the $count = 1 or more return true else return false
if($count >= 1) {
return true;
} else {
return false;
}
}
function exists($connection, $detail, $table, $row, $value) {
$query = mysqli_query($connection, "SELECT `$detail` FROM `$table` WHERE `$row` = '$value'");
$count = mysqli_num_rows($query);
if($count >= 1) {
return true;
} else {
return false;
}
}
function detail($connection, $detail, $table, $row, $value) {
$query = mysqli_query($connection, "SELECT `$detail` FROM `$table` WHERE `$row` = '$value'");
$associate = mysqli_fetch_assoc($query);
return $associate[$detail];
}
function errors($error) {
echo '<ul class="error">';
foreach($error as $fault) {
echo '<li>'.$fault.'<li>';
}
echo '</ul>';
}
function isLoggedIn() {
if(!empty($_SESSION['logged_in']) && exists($connection, 'id', 'members', 'id', $_SESSION['logged_in']) == true) {
return true;
} else {
return false;
}
}
function logout() {
unset($_SESSION['logged_in']);
}
if($_POST) {
$email = mysqli_real_escape_string($connect, strip_tags($_POST['email']));
$password = mysqli_real_escape_string($connect, strip_tags($_POST['password']));
if(!empty($email) && !empty($password)) {
if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error[] = 'Your email: '.$email.' is not valid';
}
if(exists($connection, 'email', 'members', 'email', $email) == false) {
$error[] = 'You are not registered';
}
if(detail($connection, 'active', 'members', 'email', $email) != 1) {
$error[] = 'Your account is not activated';
}
if(empty($error)) {
$query = login($connection, $email, $password);
if($query == true) {
$_SESSION['logged_in'] == detail($connection, 'id', 'members', 'email', $email);
}
}
} else {
$error[] = 'There are empty fields';
}
if(!empty($error)) {
echo errors($error);
}
}
?>
<form action="" method="POST">
Email: <input type="text" name="email"><br>
Password: <input type="password" name="password"><br>
<input type="submit" value="Login">
</form>

Cannot active my account

I'm trying secure more my member system.
So basicly if somebody wants to create an account he needs to activate it by email.
Now when I receive an email with the activation code: he says We cannot find that email This is strange since the email is in the database.
I got a script called activate.php
<?php
if (isset($_GET['succes']) === true && empty ($_GET['succes']) === true) {
?>
<h2>Thanks, your account has been activated!</h2>
<?php
} else if (isset($_GET['email'], $_GET['email_code']) === true) {
$email = trim($_GET['email']);
$email_code = trim($_GET['email_code']);
$user = new User();
if($user->email_exists($email) === false) {
echo 'We cannot find that email';
} else if ($user->activate($email, $email_code) === false) {
echo 'problem activate your account';
}
}
?>
In the classes dir I got a file called User.php
The activate function
function activate ($email, $email_code) {
$email = mysql_real_escape_string($email);
$email_code = mysql_real_escape_string($email_code);
require_once '../config.php';
if ($db->get($db->query("SELECT COUNT(`id`) FROM `users` WHERE `email` = '$email' AND `email_code` = '$email_code' AND `active` = 0"), 0) == 1) {
$db->query("UPDATE `users` SET `group` = 1 WHERE `email` = '$email'");
return true;
} else {
return false;
}
}
And the email_exists function:
function email_exists($email) {
return ($this->_db->get($this->_db->query("SELECT COUNT(`id`) FROM `users` WHERE `email` = '$email'"), 0) == 1) ? true : false;
}
Use urlencode and urldecode funcitons while inserting/gettind email from url
$email = urldecode(trim($_GET['email']));
...
$url = 'http://site/?email='urlencode($email);
Check this:
function email_exists($email) {
var_dump($email);exit;
return ($this->_db->get($this->_db->query("SELECT COUNT(`id`) FROM `users` WHERE `email` = '$email'"), 0) == 1) ? true : false;
}

I need to check my db to see if a username or email is already in use

I've started a thread or two so far but nothing has got resolved. I'm not able to use the mysqlnd because i'm using a shared hosting account with godaddy.
All i need to do is check if my email address and/or username is in use; if they are in use throw and error, if not.. all is well.
Here is my code:
$input_errors = array();
if (!empty($_POST['username'])) {
$user = $_POST['username'];
} else {
$input_errors['username'] = "Must fill out username";
}
$email = filter_input(INPUT_POST, 'usermail', FILTER_VALIDATE_EMAIL);
if (false === $email) {
$input_errors['usermail'] = "Not a valid email address";
}
if(count($input_errors) > 0) {
print_r($input_errors); die();
}
$sql = "SELECT COUNT(*) as amount FROM people WHERE username = ?
OR email = ?";
if ($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("ss", $user, $email);
$stmt->execute();
$results = $stmt->get_result();
$data = mysqli_fetch_assoc($results);
if ($data['amount'] > 0)
{
print "User already exists";
}
}
else {
$stmt = $mysqli->stmt_init();
if (!$stmt) {
echo "Init failed";
} else {
$cmd = "INSERT INTO people (username, email, sign_up_date) VALUES (?, ?, NOW() )";
if ($stmt->prepare($cmd)) {
$stmt->bind_param('ss', $user, $email );
$stmt->execute();
echo $stmt->affected_rows . " row(s) inserted";
$stmt->close();
} else {
echo "Prepare failed";
}
mysqli_close($mysqli);
}
}
bind_result() does not work.
Change your sql statement to the following:
$sql = "SELECT COUNT(*) as amount FROM people WHERE username = '".mysqli_real_escape_string($_POST['username'])."' OR email = '".mysqli_real_escape_string($email)."'";

MySQL query not updating after but PHP shows no errors

This is for user activation.
function activate($email, $email_code){
$email = mysql_real_escape_string($email);
$email_code = mysql_real_escape_string($email_code);
if (mysql_result(mysql_query("SELECT COUNT(`user_id`) FROM `users` WHERE `email` = '$email' AND `email_code` = '$email_code' AND `active` = 0"), 0) == 1){
mysql_query("UPDATE `users` SET `active` = 1 WHERE `email` = '$email'");
return true;
}else{
return false;
}
}
Activation.php
if (isset($_GET['success']) === true && empty($_GET['success'])===true){
echo 'Account activated!';
}
else if (isset($_GET['email'], $_GET['email_code']) === true){
$email = trim($_GET['email']);
$email_code = trim($_GET['email_code']);
if(email_exists($email) === false){
$errors[] = 'Oops, something went wrong!';
}else if (activate($email, $email_code === false)){
$errors[] = 'We have problems activating your account!';
}
if (empty($errors) === false){
echo output_errors($errors);
}else{
header('Location:activate.php?success');
exit();
}
}else{
header('Location:go.php');
exit();
}
It says 'Account activated!' as I echoed but it didn't change the field in the table. It didn't activate at all basically. What is the problem here?
You have to change the function like this
function activate($email, $email_code){
$email = mysql_real_escape_string($email);
$email_code = mysql_real_escape_string($email_code);
if (mysql_result(mysql_query("SELECT COUNT(`user_id`) FROM `users` WHERE `email` = '$email' AND `email_code` = '$email_code' AND `active` = 0"), 0) == 1){
if(mysql_query("UPDATE `users` SET `active` = 1 WHERE `email` = '$email'")){
return true;
}
else{
return false;
}
}
}

Categories