How would I be able to check multiple factors combined instead of checking for each one? So basically I'm using PDO and I have to make sure that the usernames and emails are unique. So how would I do that? I've seen
if ( $sthandler->rowCount() > 0 ) {
// do something here
}
But is there a better way to do it. Also if there isn't can someone explain how I'd work with that.
EDIT
Here's my query code that inputs into the database
<?php
try {
$handler = new PDO('mysql:host=localhost;dbname=s','root', '*');
$handler->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e){
exit($e->getMessage());
}
$name = $_POST['name'];
$username = $_POST['username'];
$email = $_POST['email'];
$password = $_POST['password'];
$password1 = $_POST['passwordconf'];
$ip = $_SERVER['REMOTE_ADDR'];
//Verifcation
if (empty($name) || empty($username) || empty($email) || empty($password) || empty($password1))
{
echo "Complete all fields";
}
// Password match
if ($password != $password1)
{
echo $passmatch = "Passwords don't match";
}
// Email validation
if (!filter_var($email, FILTER_VALIDATE_EMAIL))
{
echo $emailvalid = "Enter a valid email";
}
// Password length
if (strlen($password) <= 6){
echo $passlength = "Choose a password longer then 6 character";
}
function userExists($db, $user)
{
$userQuery = "SELECT * FROM userinfo u WHERE u.user=:user;";
$stmt = $db->prepare($userQuery);
$stmt->execute(array(':user' => $user));
return !!$stmt->fetch(PDO::FETCH_ASSOC);
}
$user = 'userName';
$exists = userExists($db, $user);
if(exists)
{
// user exists already.
}
else
{
// user doesn't exist already, you can savely insert him.
}
if(empty($passmatch) && empty($emailvalid) && empty($passlength)) {
//Securly insert into database
$sql = 'INSERT INTO userinfo (name ,username, email, password, ip) VALUES (:name,:username,:email,:password,:ip)';
$query = $handler->prepare($sql);
$query->execute(array(
':name' => $name,
':username' => $username,
':email' => $email,
':password' => $password,
':ip' => $ip
));
}
?>
<?php
//Connections
try {
$handler = new PDO('mysql:host=localhost;dbname=s','root', '*');
$handler->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e){
exit($e->getMessage());
}
$name = $_POST['name'];
$username = $_POST['username'];
$email = $_POST['email'];
$password = $_POST['password'];
$password1 = $_POST['passwordconf'];
$ip = $_SERVER['REMOTE_ADDR'];
//Verifcation
if (empty($name) || empty($username) || empty($email) || empty($password) || empty($password1)){
$error = "Complete all fields";
}
// Password match
if ($password != $password1){
$error = "Passwords don't match";
}
// Email validation
if (!filter_var($email, FILTER_VALIDATE_EMAIL)){
$error = "Enter a valid email";
}
// Password length
if (strlen($password) <= 6){
$error = "Choose a password longer then 6 character";
}
if(!isset($error)){
//no error
$sthandler = $handler->prepare("SELECT username FROM users WHERE username = :name");
$sthandler->bindParam(':name', $username);
$sthandler->execute();
if($sthandler->rowCount() > 0){
echo "exists! cannot insert";
} else {
//Securly insert into database
$sql = 'INSERT INTO userinfo (name ,username, email, password, ip) VALUES (:name,:username,:email,:password,:ip)';
$query = $handler->prepare($sql);
$query->execute(array(
':name' => $name,
':username' => $username,
':email' => $email,
':password' => $password,
':ip' => $ip
));
}
}else{
echo "error occured: ".$error;
exit();
}
Something like this should work:
function userExists($db, $user)
{
$userQuery = "SELECT * FROM userinfo u WHERE u.user=:user;";
$stmt = $db->prepare($userQuery);
$stmt->execute(array(':user' => $user));
return !!$stmt->fetch(PDO::FETCH_ASSOC);
}
$user = 'userName';
$exists = userExists($db, $user);
if(exists)
{
// user exists already.
}
else
{
// user doesn't exist already, you can savely insert him.
}
The code you show has no much sense to check if username and email are unique. You should set UNIQUE KEY on the database.
Related
Before completing registration I wan't to check if all submitted post values aren't empty. The POST values will be assigned to the variables only when all input fields have been filled. Else missingFields will be displayed in the URL.
So what I came up with seems to work, however I wonder if the !empty is actually going through all post values, just like individually checking all post values with !empty. If not, what should be changed?
if (!empty($_POST['first']) && ($_POST['last']) && ($_POST['email']) && ($_POST['password'])) {
// If the posts contain any values, assign them to these variables.
$first_name = $_POST['first'];
$last_name = $_POST['last'];
$mail_address = $_POST['email'];
$password = $_POST['password'];
$hash = hash('sha256', $password); // Password will be hashed.
// Check if the email already exists or not.
$existingUser = 'SELECT * FROM account WHERE sMailaddress = :mail';
$stmt = $pdo->prepare($existingUser);
$stmt->execute([
':mail' => $mail_address
]);
// When no results are found, insert values into database.
if ($stmt->rowCount() == 0) {
$registerUser = 'INSERT INTO account (sFirstname, sLastname, sMailaddress, sPassword)
VALUES (:first_name, :last_name, :mail_address, :pass)';
$stmt = $pdo->prepare($registerUser);
$stmt->execute([
':first_name' => $first_name,
':last_name' => $last_name,
':mail_address' => $mail_address,
':pass' => $hash
]);
header('Location: template/authentication.php?registrationCompleted');
} else {
header('Location: template/authentication.php?alreadyExists');
}
} else {
header('Location: template/authentication.php?missingFields');
}
$first_name = $_POST['first'];
$last_name = $_POST['last'];
$mail_address = $_POST['email'];
$password = $_POST['password'];
$hash = hash('sha256', $password); // Password will be hashed.
$check_1 = "pass";
if (empty($first_name)) {
$check_1 = "fail";
}
if (empty($last_name)) {
$check_1 = "fail";
}
if (empty($mail_address)) {
$check_1 = "fail";
}
if (empty($password)) {
$check_1 = "fail";
}
// other validation and sanitation stuff
if (($check_1 === "pass") && ($stmt->rowCount() == 0)) {
// add to database
}
you can also check user input string length and use regex to better sanitize and validate the form
I've searched through multiple threads, but I don't see exactly where is the problem in my case.
It is showing the error on line 30: $findU->bindParam(':uid', $uid);. Not really sure if that's the real problem here.
Full code:
<?php
try {
$pdo = new \PDO('mysql:host=localhost;dbname=project;charset=utf8', 'root', '', [
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);
if($_POST && isset($_POST['submit'])) {
$first = trim($_POST['first']);
$last = trim($_POST['last']);
$email = trim($_POST['email']);
$uid = trim($_POST['uid']);
$pwd = trim($_POST['pwd']);
//checks if there's an empty field
if(empty($first) || empty($last) || empty($email) || empty ($uid) || empty ($pwd)) {
header('Location: sign_up.php?signup=empty');
exit();
} else {
//checks inputs for invalid symbols through Regex
if(!preg_match("/^[a-zA-Z]/", $first) || !preg_match("/^[a-zA-Z]/", $last)) {
header('Location: sign_up.php?signup=invalid');
exit();
} else {
//checks if the email is in valid format
if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
header('Location: sign_up.php?signup=invalidemail');
exit();
} else {
//checks if the username is already in use
$findU = $pdo->prepare("SELECT * FROM `users` WHERE user_uid = ':uid'");
$findU->bindParam(':uid', $uid);
$result = $findU->execute();
if($result->fetchColumn() > 0) {
header("Location: sign_up.php?signup=usertaken");
exit();
} else {
//creating hash for password
$hashedPwd = password_hash($pwd, PASSWORD_DEFAULT);
//inserts new users into DB
$newUser = $pdo->prepare("INSERT INTO `users` (user_first, user_last, user_email,
user_uid, user_pwd) VALUES (':first', ':last', ':email', ':uid', ':hashedPwd')");
$newUser->execute(array(':first' => $first, ':last' => $last, ':email' => $email,
':uid' => $uid, ':hashedPwd' => $hashedPwd));
header("Location: sign_up.php?signup=success");
exit();
}
}
}
}
}
} catch(\PDOException $e) {
echo "Error connecting to mySQL: " . $e->getMessage();
echo "<code><pre>".print_r($e)."</pre></code>";
exit();
}
?>
I need a second pair of eyes to have a look at my code and tell me what I am missing, as I think I have identified the portion of code that doesn't work, I just don't know why.
Basically I am trying to register a user to a database, in a way that it prevents SQL injection. For the life of me however, it doesn't work. When I deconstruct the code and make it less secure, it works. Anyway, code is here:
//require_once 'sendEmails.php';
session_start();
$username = "";
$email = "";
$user_dob = "";
$user_fname = "";
$user_lname = "";
$user_telephone = "";
$errors = [];
$servername = '';
$login = '';
$password = '';
$DBname = '';
$rows = 0;
$query = "";
$conn = new mysqli($servername, $login, $password, $DBname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
if ($conn) {
echo "Connected successfully";
}
// SIGN UP USER
if (isset($_POST['signup-btn'])) {
if (empty($_POST['username'])) {
$errors['username'] = 'Username required';
}
if (empty($_POST['email'])) {
$errors['email'] = 'Email required';
}
if (empty($_POST['password'])) {
$errors['password'] = 'Password required';
}
if (isset($_POST['password']) && $_POST['password'] !== $_POST['passwordConf']) {
$errors['passwordConf'] = 'The two passwords do not match';
}
if (empty($_POST['dob'])) {
$errors['dob'] = 'Date of birth required';
}
if (empty($_POST['fname'])) {
$errors['fname'] = 'First name required';
}
if (empty($_POST['lname'])) {
$errors['lname'] = 'Last name required';
}
if (empty($_POST['telephone'])) {
$errors['telephone'] = 'Telephone number required';
} //--checks input in browser
//I think it works untill this point...
$token = bin2hex(random_bytes(50)); // generate unique token
$username = $_POST['username'];
$password = password_hash($_POST['password'], PASSWORD_BCRYPT); //encrypt password
$user_dob = $_POST['dob'];
$user_fname = $_POST['fname'];
$user_lname = $_POST['lname'];
$user_telephone = $_POST['telephone'];
$email = $_POST['email'];
//Above assigns inputted values into variables declared at the start
//echo $token, $email; //-- this works
//nl2br() ; // -- line break in php
// Check if email already exists
//$result = $mysqli->query("SELECT * FROM User_tbl WHERE email='$email' LIMIT 1");
$sql = "SELECT * FROM User_tbl WHERE email='$email' LIMIT 1";
$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > $rows) {
$errors[] = $email;
echo "Email already exists";
}
$errorsInt = count($errors);
echo mysqli_num_rows($result);
echo count($errors);
echo $errorsInt;
if ($errorsInt === $rows) {
$query = "INSERT INTO User_tbl SET token=?, username=?, password=?, user_dob=?, user_fname=?, user_lname=?, user_telephone=?, email=?";
// "INSERT INTO User_tbl VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
echo $query;
//---------------------------------------------------------------------------
$stmt = $conn->prepare($query); //first
$stmt->bind_param('sssissis', $token, $username, $password, $user_dob, $user_fname, $user_lname, $user_telephone, $email);
$result = $stmt->execute();
echo $result;
if ($result) {
$user_id = $stmt->insert_id;
$stmt->close();
$_SESSION['id'] = $user_id;
$_SESSION['username'] = $username;
$_SESSION['email'] = $email;
$_SESSION['verified'] = false;
$_SESSION['message'] = 'You are logged in!';
$_SESSION['type'] = 'alert-success';
header('location: index.php');
} else {
$_SESSION['error_msg'] = "Database error: Could not register user";
}
}
}
The problem I believe starts here:
$stmt = $conn->prepare($query); //first
$stmt->bind_param('sssissis', $token, $username, $password, $user_dob, $user_fname, $user_lname, $user_telephone, $email);
$result = $stmt->execute();
So I'm trying to make a fairly simple login system, but for some reason the hashed password that is being sent to my database is not hashing correctly. I checked my database and the stored password is not what the sha256 hashed with the generated salt appended is not what it's supposed to be. Here's my code for generating the hash that's being uploaded to the database:
<?php
include "connection.php";
//Check Connection
if ($connect->connect_error) {
echo "Failed to connect to server: " . mysqli_connect_error();
}
//Reset all Checks
$username_exists = NULL;
$email_valid = NULL;
$passwords_match = NULL;
$password_acceptable = NULL;
$password_long_enough = NULL;
$password = NULL;
//Prepare Statements
//Check for Username Existing Statement
$check_username_match = $connect->stmt_init();
$sql_check_username = "SELECT id FROM $tablename WHERE username=?";
$check_username_match->prepare($sql_check_username);
$check_username_match->bind_param("s", $username);
//Insert Into Table Statement
$register_query = $connect->stmt_init();
$sql_register = "INSERT INTO $tablename (username, email, password, token, active, level) VALUES (?, ?, ?, ?, ?, ?)";
$register_query->prepare($sql_register);
$register_query->bind_param("sssssi", $username, $email, $hashedpassword, $token, $activated, $level);
//Execute When Form Submitted
if($_SERVER["REQUEST_METHOD"] == "POST") {
$username = mysqli_escape_string($connect, $_POST['username']);
$email = mysqli_escape_string($connect, $_POST['email']);
$password = $_POST['password'];
$confirm_password = $_POST['confirm_password'];
//Check if Username Exists
$check_username_match->execute();
$check_username_match->store_result();
$numrows = $check_username_match->num_rows;
if ($numrows==0){
$username_exists = false;
} else {
$username_exists=true;
}
//Check if Passwords Match
if ($password==$confirm_password){
$passwords_match = true;
} else {
$passwords_match = false;
}
//Check if Email Address is Valid
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
$email_valid = true;
} else {
$email_valid = false;
}
//Check if Passwords Contains Special Characters
$uppercase = preg_match('#[A-Z]#', $password);
$lowercase = preg_match('#[a-z]#', $password);
$number = preg_match('#[0-9]#', $password);
//Check if Password is Long Enough
$password_length = strlen($password);
if ($password_length>8){
$password_long_enough = true;
} else {
$password_long_enough = false;
}
//Validate Password
if(!$uppercase || !$lowercase || !$number || !$password_long_enough || $password = '') {
$password_acceptable = false;
} else {
$password_acceptable = true;
}
//Register if all Validations Met
if(!$username_exists && $email_valid && $passwords_match && $password_acceptable){
//$salt = dechex(mt_rand(0, 2147483647)) . dechex(mt_rand(0, 2147483647));
$token = dechex(mt_rand(0, 2147483647)) . dechex(mt_rand(0, 2147483647));
$activated="No";
$level = 0;
$hashedpassword = password_hash($password, PASSWORD_DEFAULT);
$register_query->execute();
$message = "Hello, welcome to the site.\r\n\r\nPlease click on the following link to activate your account:\r\nlocalhost/login_system/activate.php?token=".$token;
mail($email, 'Please Activate Your Account', $message);
header("Location: login.php");
}
}
?>
UPDATE: I changed my above code to reflect the changes I made with password_hash. However, the problem still persists.
This is my login php:
<?php
include("connection.php");
session_start();
//Reset Variables
$message = '';
$location = "/login_system/index.php"; //default location to redirect after logging in
$username = '';
$password = '';
//Check to see if user is newly activated; if he is display a welcome message.
if(isset($_GET['activated'])){
if($_GET['activated'] == "true"){
$message = "Thank you for verifying your account. Please login to continue.";
}
}
//Check to see if user is coming from another page; if he is then store that page location to redirect to after logging in.
if(isset($_GET['location'])) {
$location = htmlspecialchars($_GET['location']);
}
echo $location;
//Prepare login check statement
$check_login = $connect->stmt_init();
$sql = "SELECT id, password FROM $tablename WHERE username=?";
$check_login->prepare($sql);
$check_login->bind_param("s", $username);
//Execute Login Check
if($_SERVER["REQUEST_METHOD"] == "POST") {
$username = mysqli_escape_string($connect, $_POST['username']);
$password = $_POST['password'];
$check_login->execute();
$check_login->store_result();
$numrows = $check_login->num_rows;
$check_login->bind_result($id, $match);
$check_login->fetch();
if ($numrows==1 && password_verify($password, $match)) {
$_SESSION['login_user'] = $id;
$goto = "localhost".$location;
header("location: $goto");
$message = "Success!";
} else {
$message="Username or password is not valid."."<br>".$match."<br>";
}
}
$connect->close();
?>
You should just feed the password you want to hash into PHP's password_hash();function. Like so...
$password = $_POST['password'];
$options = [
'cost' => 12,
];
echo password_hash($password, PASSWORD_BCRYPT, $options);
Then when you want to check if the password exists in the database use password_verify(); Like so...
$password = PASSWORD_HERE;
$stored_hash = HASH_HERE;
if (password_verify($password, $stored_hash)) {
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}
Problem & Explanation
Hello I have just coded a function that first does checking if account exists in database with that name, and then if email exists in database with that entered email.
If not, return true + insert data.
But in this case, nothing happens on submit, it just shows the form, but doesn't inserts the data..
What is wrong with it?
function createAccount($name, $password, $email)
{
global $pdo;
$check_in = $pdo->prepare("SELECT * FROM users WHERE user_name = :username LIMIT 1");
$check_in->execute( array(':username' => $name) );
if (!$check_in->rowCount())
{
$check_in = email_exists($email);
if ($check_in === false)
{
$insert_in = $pdo->prepare
("
INSERT INTO
users
(user_name, user_password, user_email)
VALUES
(:name, :password, :email)
");
$insert_in->execute( array
(
':name' => $name,
':password' => $password,
':email' => $email
));
return true;
}
else
{
return 'exists';
}
}
else
{
return 'user_in_use';
}
}
function email_exists($email)
{
global $pdo;
$check = $pdo->prepare("SELECT * FROM users WHERE user_email = :email LIMIT 1");
$check->execute( array(':email' => $email) );
if ($check->rowCount())
{
return true;
}
else
{
return false;
}
}
This is how I make up the register:
# Creating shortcuts
if (isset($_POST['username']) && isset($_POST['password']) && isset($_POST['email']))
{
$name = $_POST['username'];
$password = $_POST['password'];
$email = $_POST['email'];
}
# Creating errors array
$errors = array();
if (isset($_POST['submit']))
{
$check_in = createAccount($name, $password, $email);
if ($check_in === true)
{
echo 'Created account sucessfully!';
}
else if ($check_in == 'already_in_use')
{
echo 'Could not create account because name already in use..';
}
else if($check_in == 'exists')
{
echo 'Email already in use..';
}
}
Question:
What is wrong with this code & how do I fix this? I have no errors at all.
It just won't insert any data to the Database.
Yes, the PDO connection & statements are right, because the login works perfectly.
Thanks a lot!
EDIT!
if ($check_in === true)
{
echo 'Created account sucessfully!';
}
else if ($check_in == 'already_in_use')
{
echo 'Could not create account because name already in use..';
}
else if($check_in == 'exists')
{
echo 'Email already in use..';
} else {
echo 'Error is there...';
}
It's echoing 'Error is there...' apon submit!
I just want to slap myself!.....
The problem was: The fields were set as INT, therefore we could not store anything but ints...