I have this code
$con = new mysqli('####', '####', '####', '####');
if(mysqli_connect_errno()){
echo 'Connection Failed:' . mysqli_connect_errno();
exit();
}
//Variables
$user = $_POST['username'];
$zone = $_POST['password'];
$pass = strtoupper(hash("whirlpool", $zone));
//Prepare
if($stmt = $con -> prepare("SELECT * FROM `accounts` WHERE Username=? AND Key=?")){
$stmt -> bind_param("ss", $user, $pass);
$stmt -> execute();
$stmt -> bind_results($result);
$stmt -> fetch();
if($result) {
$_SESSION['username'] = $user;
$url = 'home.php';
echo '<META HTTP-EQUIV=Refresh CONTENT="1; URL='.$url.'">';
} else {
echo 'Login Failed';
}
}
?>
I am new to Prepared statements and I cannot get it to work.
Upon trying to log in I just get a blank white page with no error. I know I am connected to the db because if I remove the prepared statement and do it the unsecured way everything logs in just fine.
Please note. I have just been looking up tutorials on prepared statements so I can learn to code more securely. I am in no way a pro with this. Any tips would be greatly appreciated.
Warning: mysqli_stmt::bind_result(): Number of bind variables doesn't
match number of fields in prepared statement in
C:\xampp\htdocs\newsystem\loginadd.php
That's because you select * (all fields). You should be more specific about the fields you want to get (for example SELECT id FROM ...).
Have a look at examples on PHP doc: 2 fields are selected, 2 parameters for bind_result().
According to #AbrikChakraborty comment you just need add backticks to your field name:
if($stmt = $con -> prepare("SELECT * FROM `accounts` WHERE Username=? AND `Key`=?")){
and according to #caCtus comment:
$stmt -> bind_result($result);
and if you really want to bind unknown number of fields returned you can check this answer or just use PDO.
Verify the actual query, if it fetches the result. I doubt the query itself returns empty result.
"SELECT * FROM `accounts` WHERE Username=$user AND Key=$pass"
Related
I am trying to build an override feature so users can manually remove a MySQL table row if they have the correct rights to do so. The user is prompted to input the same credentials used for program login as well as the uniqueID for the row that needs to be removed. Upon hitting the 'Submit' function, I run a series of if statements/ MySQL SELECT statements to check credentials, user rights and finally row Deletion with the result output as an alert.
However, my alert shows up blank and the row is not removed so I know there is a problem with my if statements. Upon testing, I believe the problem is when I try to use the previous query's results to run the next if statement logic.
How do I properly determine if the MySQL query returned a row using prepared statements?
All help is appreciated! Thank you!
My CODE:
if ((isset($_POST['overrideUsername'])) and (isset($_POST['overridePassword'])) and (isset($_POST['overrideUniqueID']))) {
$overridePasswordInput = $_POST['overridePassword'];
$overrideUsername = $_POST['overrideUsername'];
$overridePassword = ENCODE(($overridePasswordInput).(ENCRYPTION_SEED));
$roleID = '154';
$overrideUniqueID = $_POST['overrideUniqueID'];
//connect to the database
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if(mysqli_connect_errno() ) {
printf('Could not connect: ' . mysqli_connect_error());
exit();
}
$conn->select_db($dbname);
if(! $conn->select_db($dbname) ) {
echo 'Could not select database. '.'<BR>';
}
$sql1 = "SELECT users.id FROM users WHERE (users.login = ?) AND (users.password = ?)";
$stmt1 = $conn->prepare($sql1);
$stmt1->bind_param('ss', $overrideUsername, $overridePassword);
$stmt1->execute();
$stmt1->bind_result($userID);
//$result1 = $stmt1->get_result();
if ($stmt1->fetch()) {
$sql2 = "SELECT * FROM rolestousers WHERE (rolestousers.userid = ?) AND (rolestousers.roleid = ?)";
$stmt2 = $conn->prepare($sql2);
$stmt2->bind_param('ss', $userID, $roleID);
$stmt2->execute();
$stmt2->store_result();
if ($stmt2->fetch()) {
$sql3 = "DELETE * FROM locator_time_track_out WHERE locator_time_track_out.uniqueid = ?";
$stmt3 = $conn->prepare($sql2);
$stmt3->bind_param('s', $overrideUniqueID);
$stmt3->execute();
$stmt3->store_result();
if ($stmt3->fetch()) {
echo 'Override Successful! Please scan the unit again to close it out.';
} else {
echo 'Could Not Delete Record from the table.';
}//End $sql3 if.
} else {
echo 'User does not have override permission. Please contact the IT Department.';
}//End $sql2 if.
} else {
echo 'Your login information is incorrect. Please try again. If the issue persists, contact the IT Department.';
}//End $sql1 if.
//Free the result variable.
$stmt1->free();
$stmt2->free();
$stmt3->free();
$stmt1->close();
//Close the Database connection.
$conn->close();
}//End If statement
NOTE: I am definitely sure my DB connection information is correct. The issue resides after I connect into the database. I have also tested the code using only the first if statement and get the blank alert so I'm not making it past the first if statement.
EDIT:: My php Script was definitely failing, but even earlier than expected, at the following code:
$overridePassword = ENCODE(($overridePasswordInput).(ENCRYPTION_SEED));
So my issue is that I need to properly compare the password and encryption seed information. However, the previous programmer used the following line to do the same process (which is obviously unsafe):
$querystatement = "SELECT id, firstname, lastname, email, phone, department, employeenumber, admin, usertype FROM users WHERE login=\"".mysql_real_escape_string($user)."\" AND password=ENCODE(\"".mysql_real_escape_string($pass)."\",\"".mysql_real_escape_string(ENCRYPTION_SEED)."\")";
$queryresult = $this->db->query($querystatement);
I will need to fix this issue before I can even test the functionality of the if logic using prepared statements.
Your are passing wrong variable for delete query
$stmt3 = $conn->prepare($sql3);
Please refer [ http://www.plus2net.com/php_tutorial/pdo-delete.php ]
On my form page, I have two textboxes with the names name and password.
When the user hits submit, it sends that data into two columns in a MySQL database named 'name' and 'password'.
After the data is recorded (which is the part I understand and don't need help with), I want the user to be at the sign-in page and type in his/her name and password and only be allowed into the site if the name and password data already exist in the database (part that I don't understand).
Would I use the following query :
SELECT * FROM tablename WHERE name & password = "'$_POST[name]', $_POST[password]'
You should use AND or && instead of just a single ampersand (&), and separate the variables to be binded accordingly to their column name.
You should also consider sanitizing your variables before using them to your queries. You can use *_real_escape_string() to prevent SQL injections.
$name = mysql_real_escape_string($_POST["name"]);
$password = mysql_real_escape_string($_POST["password"]);
"SELECT * FROM tablename WHERE name = '".$name."' AND password = '".$password."'"
But the best recommendation that I can give to you is to use prepared statement rather than the deprecated mysql_*
if($stmt = $con->prepare("SELECT * FROM tablename WHERE name = ? AND password = ?")){ /* PREPARE THE QUERY; $con SHOULD BE ESTABLISHED FIRST USING ALSO mysqli */
$stmt->bind_param("ss",$_POST["name"],$_POST["password"]); /* BIND THESE VARIABLES TO YOUR QUERY; s STANDS FOR STRINGS */
$stmt->execute(); /* EXECUTE THE QUERY */
$noofrows = $stmt->num_rows; /* STORE THE NUMBER OF ROW RESULTS */
$stmt->close(); /* CLOSE THE STATEMENT */
} /* CLOSE THE PREPARED STATEMENT */
For securing password, you could also look at password_hash().
Please Always use Prepared statement to execute SQL code with Variable coming from outside your code. Concatenating variable from user input into SQL code is dangerous ( consider SQL injection ), you could use prepared statement with mysqli or PDO ( recommended ).
Mysqli example:
$mysqli = new mysqli("example.com", "user", "password", "database");
// error check you connection here
$query='select * from tablename where user =? AND password=?';
$stmt = $mysqli->prepare($query);
$stmt->bind_param("ss", $user,$password);
$stmt->execute();
if($stmt->num_rows!=1) {
// check failed
}else{
// check success
}
PDO example (recommended )
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
// error check you connection here
$query='select * from tablename where user =? AND password=?';
$stmt = $dbh->prepare($query);
$stmt->bindParam(1,$user);
$stmt->bindParam(2,$password);
$stmt->execute();
if($sth->fetchAll()) {
// check success
}else{
// check failure
}
Additionally you should also consider using some form of 1-way password encryption ( password hashing ) before storing it in your database and compare it to the hash( the most accepted way to do it is using Bcrypt).
You can use something like
SELECT count(*) FROM tablename WHERE name = "'.$_POST[name].' AND password = "'. $_POST[password].'"
You should expect count to be exactly 1 - indicating valid user, 0 - indicating invalid user
Anything greater than 1 should be invalid scenario indicating some kind of inconsistency in your database...
You should assign the variables to name & pass subsequently.
You can try this:
$con = mysqli_connect("localhost","YOURUSER","YOURPASS","YOURDB");
if (mysqli_connect_errno())
{
echo"The Connection was not established" . mysqli_connect_error();
$user
= mysqli_real_escape_string($con,$_POST['user']);
$pass = mysqli_real_escape_string($con,$_POST['password']);
$query = "select * from tablename where user ='$user' AND password='$pass' ";
$run = mysqli_query($con,$query);
$check = mysqli_num_rows($run );
if($check == 0)
{
echo "<script> alert('Password or Email is wrong,try again!')</script>";
}
else
{
//get a session for user
$_SESSION['user']=$user;
// head to index.php; you can just put index.php if you like
echo"<script>window.open('index.php?login=Welcome to Admin Area!','_self')</script>";
}
This is the code, following (Explanation is afterwards):
<?php
error_reporting(E_ALL);
ini_set('display_errors',1);
$uname = $_POST['uname'];
if($uname!=""){
$mysqli = new mysqli('localhost', 'root', '', 'dota_site_test');
if(mysqli_connect_errno()){
echo("connetion error: " . mysqli_connect_errno());
exit();
}
$stmt = $mysqli->prepare("SELECT Username FROM users WHERE Username=?");
$stmt -> bind_param("s", $uname);
$stmt -> execute();
$stmt -> bind_result($unamecheck);
if($stmt->num_rows > 0){
echo "taken: ";
echo "name is ".$unamecheck;
}else{
echo "free: ";
echo "name is ".$unamecheck;
}
$stmt -> close();
$mysqli -> close();
}
?>
I am not sure where the problem is, but when I am, at the bottom, trying to echo "name is ". $unamecheck;, It is just returning blank. The way this code works is that on every key press the query is run to see if a Username is already present in the database. I have checked my Ajax, and the $uname = $_POST['uname']; is working fine.
In addition, I have ran the query "SELECT Username FROM users WHERE Username=?" within mysql itself, replacing the ? with my username, and that worked fine.
Have I made a mistake with the prepared statement? I am not sure if this is the way it must be done, but I am trying to be careful with SQL injection.
The result of my testing just shows free: name is being echo'd regardless of input. No other error codes are present.
You need to call
$stmt -> fetch();
After
$stmt -> bind_result($unamecheck);
In the prepare query, try to separete the =? from the column name, like this:
SELECT Username FROM users WHERE Username = ?
If this not work, print mysql_error() to verify if there is a mysql error
I apologise if the title is poor.
I have been researching Prepared Statements and found the following code here:
/* Create a new mysqli object with database connection parameters */
$mysqli = new mysqli('localhost', 'username', 'password', 'db');
if(mysqli_connect_errno()) {
echo "Connection Failed: " . mysqli_connect_errno();
exit();
}
/* Create a prepared statement */
if($stmt = $mysqli -> prepare("SELECT priv FROM testUsers WHERE username=?
AND password=?")) {
/* Bind parameters
s - string, b - blob, i - int, etc */
$stmt -> bind_param("ss", $user, $pass);
/* Execute it */
$stmt -> execute();
/* Bind results */
$stmt -> bind_result($result);
/* Fetch the value */
$stmt -> fetch();
echo $user . "'s level of priviledges is " . $result;
/* Close statement */
$stmt -> close();
}
/* Close connection */
$mysqli -> close();
The part that I don't understand, is how in the SQL Query "SELECT priv FROM testUsers WHERE username=?
AND password=?"), the system knows what the username and password is. I know that the ? marks are placeholders, and below is also confusing me a bit:
$stmt -> bind_param("ss", $user, $pass);
Because I do not see how the $user and $pass have been defined at any point, and thus how the SQL query will substitute the $user and $pass for an actual string. If that makes sense. Where have these values come from? Where are they in this example?
That's because they aren't. This is probably just an example how to use the script. You will have to define the $user and $pass variables by yourself, for example from an $_POST variable of some sort.
The bind_param function handles the arguments. You have to add the same amount of arguments to the query as you put question marks in it. Than the parser in the core of MySQLi can add the arguments safely to the query.
They are being matched by order. Same logic in string building ("{0} is greater than {1}", "5", "3") becomes 5 is greater than 3. So with parameters
$stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent);
they are all ordered and matches with columns.
If the original script writer had register_globals ON, e.g. in a previous version of PHP, then the user and pass were passed in from the form in the same way as $_POST['user'] and $_POST['pass']. I offer that you can replace them now and move on.
Can I do a WHERE clause inside an IF statement?
Like I want something like this:
$SQL = mysql_query("SELECT * FROM `table` ORDER BY `row` DESC");
$rows = mysql_fetch_array($SQL);
$email = $_SESSION['email_of_user'];
if($rows["row"] == "1" WHERE `row`='$email' : ?> (Pulls the logged in user's email)
Edit Server
<?php else : ?>
Add Server
<?php endif; ?>
Do I need (" where the WHERE statement is? Because I tried that and it didn't seem to work...
Or can I do it with an if condition inside of a where clause? Not sure of all these terms yet so correct me if I'm wrong...
You cannot mix up a query statement with PHP's statement. Instead write a query extracting desired results and check if there are any rows from that query.
I will show you an example:
$query = "SELECT * FROM `TABLE_NAME` WHERE `field` = '1' && `email`='$email'"; //Create similar query
$result = mysqli_query($query, $link); //Query the server
if(mysqli_num_rows($result)) { //Check if there are rows
$authenticated = true; //if there is, set a boolean variable to denote the authentication
}
//Then do what you want
if($authenticated) {
echo "Edit Server";
} else {
echo "Add Server";
}
Since Aaron has shown such a effort to encourage safe code in my example. Here is how you can do this securely. PDO Library provides options to bind params to the query statement in the safe way. So, here is how to do it.
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass); //Create the connection
//Create the Query Statemetn
$sth = $dbh->prepare('SELECT * FROM `TABLE_NAME` WHERE field = :field AND email = :email');
//Binds Parameters in the safe way
$sth -> bindParam(':field', 1, PDO::PARAM_INT);
$sth -> bindParam(':email', $email, PDO::PARAM_STRING);
//Then Execute the statement
$sth->execute();
$result = $sth->fetchAll(); //This returns the result set as an associative array