Check if username/email available method - php

I try to make a secure method that checks if a username or email is not taken and I'm not sure if this is the right way. How can I do this better?
private function checkAvailability() {
try {
$conn = new PDO(DB_SERVER, DB_USER, DB_PASS);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = ("SELECT COUNT(*) FROM users WHERE username = :username OR email = :email");
$st = $conn->prepare($sql);
$st->bindValue(":username", $_POST["username"], PDO::PARAM_STR);
$st->bindValue(":email", $_POST["email"], PDO::PARAM_STR);
$st->execute();
if($st->fetchColumn() > 0) {
$sql = ("SELECT COUNT(*) FROM users WHERE username = :username");
$st = $conn->prepare($sql);
$st->bindValue(":username", $_POST["username"], PDO::PARAM_STR);
$st->execute();
if($st->fetchColumn() > 0) {
throw new Exception("That username is already taken");
} else {
throw new Exception("That e-mail is already registered.")
}
return 0;
} else {
return 1;
}
$conn = null;
} catch (PDOException $e) {
echo "Database error: " . $e->geMessage();
} catch (Exception $e) {
echo "Registration failed: " . $e->geMessage();
}
}
public function registerUser() {
if(self::checkAvailability) {
// register user
}
}

You are already on the right path here.
The query SELECT COUNT(*) FROM users WHERE username = :username OR email = :email can be a performance problem, because the db can't use any index here. So you might want to split that in two statements one for username and one for email. That would also help you determining which error occured.
Also you don't need every hit in the db just the first, so a limit 1 is also usefull.

Related

Can't figure out this bindParam issue

I'm trying to fetch some data from a MySql db using PDO but no matter what I do, I can't get anything when using a prepared statement... please tell me what I'm doing wrong.
The following code runs but returns nothing.
try {
$dbh = new PDO('mysql:host=localhost;dbname=banim', 'root', '');
$uName = "banim"; //$_POST['uName'];
$email = "Rabak#gmail.com"; //$_POST['email'];
$query = $dbh->prepare("SELECT * from users WHERE email = :email OR WHERE uName = :name");
$query->setFetchMode(PDO::FETCH_ASSOC);
$query->bindParam(":name", $uName);
$query->bindParam(":email", $email);
$query->execute();
foreach ($query as $row) {
print_r($query);
}
} catch (PDOException $e) {
echo "PDOException: " . $e->getMssage() . PHP_EOL;
}
What Alive To Die wrote was correct, and there was also an extra WHERE in the SQL string which also messed up the answer, this is the final code:
try {
$dbh = new PDO('mysql:host=localhost;dbname=banim', 'root', '');
$uName = "banim"; //$_POST['uName'];
$email = "Rabak#gmail.com"; //$_POST['email'];
$query = $dbh->prepare("SELECT * from users WHERE email = :email OR uName = :name");
$query->setFetchMode(PDO::FETCH_ASSOC);
$query->bindParam(":name", $uName);
$query->bindParam(":email", $email);
$query->execute();
while($row = $query->fetch()){
print_r($row);
}
} catch (PDOException $e) {
echo "PDOException: " . $e->getMssage() . PHP_EOL;
}

How do I make an if statement which checks if a variable is in the mysql database

try {
$conn = new PDO("mysql:host=" . $_GLOBALS['servername'] . ";dbname=". $_GLOBALS['dbname'], $_GLOBALS['username'], $_GLOBALS['password']);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT * FROM us WHERE username='$suser' and password='$shashpass'"; // SQL Query
$conn->exec($sql);
Thats some of my code, how do I make it so if suser and shashpass are correct it can
execute some code, else it executes other code
This won't work either
<?php
try
{
$conn = new PDO("mysql:host=" . $_GLOBALS['servername'] . ";dbname=". $_GLOBALS['dbname'], $_GLOBALS['username'], $_GLOBALS['password']);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$query = $con->prepare("SELECT * FROM us WHERE username=:user and password=:password"); $query->bindParam(':user',$suser);
$query->bindParam(':password',$shashpass); $query->execute(); $result = $query->fetch(PDO::FETCH_ASSOC);
if(!empty($result)){ } else { } }
catch(PDOException $e) {
echo $sql . $e->getMessage();
}
You don't pre-hash the password when verifying it. Instead you SELECT the password hash from that user (if it exists) and then use password_verify() to verify that it's correct based on the plain text password sent by the web form.
$stmt = $conn->prepare("SELECT password FROM us WHERE username=?");
$stmt->execute([$suser]);
if ($user = $stmt->fetch(PDO::FETCH_ASSOC)) {
if (password_verify($plain_text_password, $user['password'])) {
// Successful login
}
else {
// Valid user, but invalid password
}
}
else {
// User doesn't exist
}
If you're not using password_hash() and password_verify(), You're Doing It Wrong™.
you are using PDO in wrong way , you need to use prepared statements in PDO to be secure from mysql injections, try to use the code below:
try {
$conn = new PDO("mysql:host=" . $_GLOBALS['servername'] . ";dbname=". $_GLOBALS['dbname'], $_GLOBALS['username'], $_GLOBALS['password']);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$query = $con->prepare("SELECT * FROM us WHERE username=:user and password=:password");
$query->bindParam(':user',$suser);
$query->bindParam(':password',$shashpass);
$query->execute();
$result = $query->fetch(PDO::FETCH_ASSOC);
if(!empty($result)){
// user is in database
} else {
// user is not there
}
exec will return the number of affected rows so:
$rows = $conn->exec($sql);
if($rows > 0){
//suser and shashpass are correct
}else{
//suser and shashpass are incorrect
}
//Use below PDO code
<?php
try {
$conn = new PDO("mysql:host=$servername;dbname=myDB", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
$sql = "SELECT * FROM us WHERE username='$suser' and password='$shashpass'";
// SQL Query
$conn->exec($sql);
}
catch(PDOException $e)
{
echo "Connection failed: " . $e->getMessage();
}
?>

Why does my pdo statement result always return true?

I am converting an old login script from mysql_query into pdo and I am struggling somewhat
All I am trying to do is find out of an email exist in the database or not!
My Code
public function doesEmailExist($userEmail)
{
$db = new PDO('mysql:host=localhost;dbname=servershop', 'user', 'pass');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $db->prepare("SELECT COUNT(`uid`) FROM `user` WHERE `email`= ?");
$stmt->bindValue(1, $userEmail);
try
{
$stmt->execute();
$rows = $stmt->fetchColumn();
if($rows == 1)
{
return true;
}
else
{
return false;
}
}
catch (PDOException $e)
{
die($e->getMessage());
}
}
Regardless of if the email exists in the table or not, the code is always returning true?
Is there not a simple way to do this like count_rows in sql?
Change this:
$rows = (int) $stmt->fetchColumn();
And it should work.

Why are users who do not exist allowed to login using this bit of script?

I have some PDO:
if (empty($this->user->username) || empty($this->user->password))
throw new Exception("Error Processing Request", 1);
include('dbconnect.php'); // Normally I'd store the db connect script outside of webroot
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name;", $db_user, $db_password);
$stmt = $pdo->prepare('SELECT userFName FROM Users WHERE username = ? AND password = ? AND roleID = 1');
$stmt->bindParam(1, $this->user->username);
$stmt->bindParam(2, $this->user->password);
$stmt->bindColumn(1, $userFName, PDO::PARAM_STR);
try {
$stmt->execute();
}
catch (PDOException $e) {
echo 'Invalid username or password: ' . $e->getMessage();
}
$stmt->fetch(PDO::FETCH_BOUND);
$this->user->firstName = $userFName;
If the POSTed username and/or password are wrong, a login still occurs. I think something is wrong with the PDO; did I miss something critical when trying to check $this->user->password against the record in the DB?
(btw, I am using encryption)
$stmt->execute();
will not throw an exception if there are no results. You need to check if the query result returned a row for the user.
edit:
$stmt->execute();
if ($stmt->rowCount() > 0) {
//user found
} else {
//user not found
}

Login script using PDO extension not working

I am unsure if I am doing it properly but I just started working with PDO and I am not able to get my code to work. I continue to get the error "sorry could not connect" and I am unable to figure out what is wrong.
Included below is the code that I am using:
function doRun( $data )
{
try
{
$db = new PDO('mysql:host=localhost;dbname=testData', 'root', 'root');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $db->prepare(' SELECT
username, pass
FROM
testTable
WHERE
username = :name
AND
pass = :pass
');
$stmt->bindParam(':name', $username, PDO::PARAM_STR);
$stmt->bindParam(':pass', $pass, PDO::PARAM_STR);
$stmt->execute();
//$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
$result = $stmt->fetchColumn();
if($result == false)
{
echo 'sorry could not connect';
}
else
{
$_SESSION['username'] = $user;
echo 'logged in as' . $user;
}
}
catch (PDOException $e)
{
echo "throw";
}
$db = NULL;
}
This would give you 0 rows as it seems that $username and $pass are not defined:
$stmt->bindParam(':name', $username, PDO::PARAM_STR);
$stmt->bindParam(':pass', $pass, PDO::PARAM_STR);
^^^^^^^^^
You probably want some elements from $data variable you are feeding to the function as a username and password.
Later on you are using a variable $user that is undefined as well.
What does $data contain?
The reason that you are "unable to connect", even though you are connecting but you're not finding a match, is because your user variables are not defined.
Try the following solution:
<?php
function doRun( $data )
{
$msg = '';
$username = isset($_POST['name']);
$pass = isset($_POST['pass']);
try
{
$db = new PDO('mysql:host=localhost;dbname=testData', 'root', 'root');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $db->prepare('
select
username
,pass
from
testTable
where
username = :name
and pass = :pass
');
$stmt->execute(array(':name' => $username, ':pass' => $pass);
$result = $stmt->fetchAll();
if(!empty($result)){
$_SESSION['username'] = $user;
$msg = "logged in as $user";
}else{
$msg = "Unable to connect";
}
} catch (PDOException $e) {
echo "Error: $e";
}
echo $msg
$db = NULL;
}
?>

Categories