This code should check for existing usernames and if there isn't one, it should create a new one. No matter what it won't add. Additionally, as you can see in the code it only echoes 'here' and doesn't echo 'not here'.
<?php
$password = "hey";
$username = "hi";
require "conn.php";
//$password = $_POST["password"];
//$username = $_POST["username"];
echo 'here';
$result = $conn->query("SELECT * FROM UserData WHERE username ='$username' ", MYSQLI_USE_RESULT);
echo 'not here';
if ($result) {
if($result->num_rows === 0)
{
$stmt = $conn->prepare("INSERT INTO UserData (username,password) VALUES (:username,:password)");
$params = array(
':username' => $username,
':password' => $password
);
$stmt->execute($params);
}
}
?>
This is the connection code:
<?php
//$db_name = "xxx";
//$mysql_username = "xxx";
//$mysql_password = "xxx";
//$server_name = "xxx";
// Create connection
$conn = new mysqli("xxx","xxx","xxx","xxx");
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "Connected successfully";
?>
Changes:
<?php
require "conn.php";
echo "debug 1";
$stmt = $conn->prepare("SELECT * FROM UserData WHERE username = ?");
$stmt->bind_param('s', /*$_POST["username"]*/ $username );
$username = 'hi';
$stmt->execute();
$stmt->store_result();
echo "debug 2";
if ($stmt->num_rows == 0){ // username not taken
echo "debug 3";
$stmt2 = $conn->prepare("INSERT INTO UserData (username, password) VALUES (?, ?)");
$password =(/*$_POST["password"]*/ "hey");
$username =(/* $_POST["username"]*/ "hi");
$stmt2->bind_param('s',$username);
$stmt2->bind_param('s',$password);
$stmt2->execute();
if ($stmt2->affected_rows == 1){
echo 'Insert was successful.';
}else{ echo 'Insert failed.';
var_dump($stmt2);
}
}else{ echo 'That username exists already.';}
?>
This code gets through all of the debugs but for some reason, it is still not inserting.
Replace this line
$result = **$mysqli->**query("SELECT * FROM UserData WHERE username ='$username' ", MYSQLI_USE_RESULT);
with following
$result = **$conn->**query("SELECT * FROM UserData WHERE username ='$username' ", MYSQLI_USE_RESULT);
The mysqli and PDO interfaces must not be mixed. Here the database connection and the SELECT query are both using the mysqli interface. But the second INSERT query is attempting to use the PDO interface, as evidenced by the use of named placeholders, and also the passing of a data array directly to execute(). The latter two features are not supported by mysqli, hence the code fails at the second query. Also, note that the second query is using prepared statements, while the first one is not. Again, different approaches should not be mixed together.
Also it appears that passwords are being stored as plain text, with no security. The proper approach is to use the password_hash function.
Just ensure that the database field has enough width (say 80-120 characters or more) to handle the current bcrypt hash, plus allow some more for future changes.
Staying with the mysqli interface (and with password_hash), the code could go something like this:
$stmt = $conn->prepare("SELECT * FROM UserData WHERE username = ?");
$stmt->bind_param('s', $_POST["username"]);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 0){ // username not taken
$stmt2 = $conn->prepare("INSERT INTO UserData (username, password) VALUES (?, ?)");
$password = password_hash($_POST["password"], PASSWORD_DEFAULT);
$stmt2->bind_param('s', $_POST["username"]);
$stmt2->bind_param('s', $password);
$stmt2->execute();
if ($stmt2->affected_rows == 1)
echo 'Insert was successful.';
else echo 'Insert failed.';
}
else echo 'That username exists already.';
Note that the above approach would not be suitable for a high-traffic site, where there is a chance condition of another user trying to INSERT the same username, during the brief interval of time between the SELECT and INSERT database queries. That would require a different approach, like ensuring the subject database field is set to UNIQUE (which is good practice anyway), and then testing for violation of that UNIQUE field upon attempted duplicate insertion.
Assuming database and INSERT permissions are all set up OK and it is still not inserting, try enhancing the error-reporting.
Ensure the following are at the top of the page:
ini_set('display_errors', true);
error_reporting(E_ALL);
And put the following before the first query:
$driver = new mysqli_driver();
$driver->report_mode = MYSQLI_REPORT_ALL;
Then try again.
Related
I'm trying to execute a parameterized query to update some stuff in the database.
The problem is that it mysqli_stmt_prepare fails.
The require is used to connect to the database.
require 'includes/dbInclude.php';
if ($codeQuery > 0){
$confirmationUsername = $_GET['confirmationUsername'];
$active = "active";
$noCode = "";
$insertSql = "UPDATE users SET accountStatus = ? WHERE username = $confirmationUsername";
$insertSql2 = "UPDATE users SET confirmationCode = ? WHERE username = $confirmationUsername";
$statement = mysqli_stmt_init($connection);
$statement2 = mysqli_stmt_init($connection);
if (!mysqli_stmt_prepare($statement, $insertSql)){
header("Location: registerComplete.php?error=sqlError1");
exit();
}
elseif (!mysqli_stmt_prepare($statement2, $insertSql2)){
header("Location: registerComplete.php?error=sqlError2");
exit();
}
else{
mysqli_stmt_bind_param($statement, "s", $active);
mysqli_stmt_execute($statement);
mysqli_stmt_bind_param($statement2, "s", $noCode);
mysqli_stmt_execute($statement2);
}
}
dbInclude.php contains:
<?php
//connection variables
$serverName = "localhost";
$dbUsername = "root";
$dbPassword = "";
$dbName = "ecglive";
//connection
$connection = mysqli_connect($serverName, $dbUsername, $dbPassword, $dbName);
//connection error
if(!$connection){
die("There was an error connceting to the database: " . mysqli_connect_error());
}
And where I used it works. I alos tried copy that code to this one just to see if there was any problem connecting to the database. It isn't.
It always goes on the first error if, where it says sqlError1 and if I delete it, then it goes to the sqlError2.
Did I make any mistake?
You need to bind the username in addition to the accountstatus to help mitigate SQL injection.
require 'includes/dbInclude.php';
if ($codeQuery > 0){
$confirmationUsername = $_GET['confirmationUsername'];
$active = "active";
$noCode = "";
$insertSql = "UPDATE users SET accountStatus = ? WHERE username = ?";
$insertSql2 = "UPDATE users SET confirmationCode = ? WHERE username = ?";
$statement = mysqli_stmt_init($connection);
$statement2 = mysqli_stmt_init($connection);
if (!mysqli_stmt_prepare($statement, $insertSql)){
exit(header("Location: registerComplete.php?error=sqlError1") );
} elseif (!mysqli_stmt_prepare($statement2, $insertSql2)){
exit(header("Location: registerComplete.php?error=sqlError2") );
} else{
mysqli_stmt_bind_param($statement, "ss", $active,$confirmationUsername);
mysqli_stmt_execute($statement);
mysqli_stmt_bind_param($statement2, "ss", $noCode,$confirmationUsername);
mysqli_stmt_execute($statement2);
}
}
This code uses a very strange style, and one that's far more verbose than necessary. Here's a more minimal form of same:
require 'includes/dbInclude.php';
// Enable exception reporting
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
if ($codeQuery > 0) {
try {
// Prepare one query that sets both properties.
$stmt = $connection->prepare('UPDATE users SET accountStatus=?,confirmationCode=? WHERE username=?');
// Bind parameters directly form the source, no variables needed.
$stmt->bind_param('ss', 'active', '', $_GET['confirmationUsername']);
// Attempt to execute
$stmt->execute();
}
catch (Exception $e) {
// Error handling here...
header("Location: registerComplete.php?error=sqlError2");
exit();
}
}
You're really not doing a lot here, so there's no reason for that code to be so verbose.
That being said, if this is a registration system for some kind of user access control layer and this isn't an academic project you should stop working on this code before you create a huge mess. Writing your own access control layer is not easy and there are many opportunities to get it severely wrong.
Any modern development framework like Laravel comes with a robust authentication system built-in. This is a solved problem and there's no need for you to try and re-invent the wheel here.
At the absolute least follow recommended security best practices and never store passwords as plain-text or a weak hash like SHA1 or MD5.
I am currently working trying to use the statements mysqli_prepare and bind_param in order to pass arguements more safely into my query. I was doing mysqli_query to execute them before which worked fine. My professor is requiring us to use prepare though. I currently am getting the proper values from my form but the data isn't being entered into customer table. Also, I have mysqli_error() on my execute() commands but I am not getting any errors at all which is making debugging difficult. Here is the php part located in register.php
<?php
require 'connection.php';
$result = "";
if(isset($_POST['register'])) {
#Fetch the data from the fields
$username = $_POST['username'];
$password = $_POST['password'];
$name = $_POST['name'];
$total = 0.0;
#echo $username . " " . $password . " " . $name . " " . $total;
#Prepare sql query to see if account already exists
$query = mysqli_prepare("SELECT * FROM customer WHERE username=?");
$query->bind_param("s", $username);
$query->execute() or die(mysqli_error());
if(mysqli_num_rows($query) > 0) {
#This username already exists in db
$result = "Username already exists";
} else {
$insert = mysqli_prepare("INSERT INTO customer(username, password, name, total) VALUES (?, ?, ?, ?)");
$insert->bind_param("sssd", $username, $password, $name, $total);
$insert->execute() or die(mysqli_error());
#$result = "Account registered!"
}
}
?>
I establish connection to my db like this in connection.php
$conn = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
Like I said before, I can get the query to execute with mysqli_query but for some reason I cannot get param to work. Also tried adding or die but no errors are being printed
So im making a login for a game system that uses a JSON string to read back the files, however when I Hash the password and try login it doesn't work however when the password is unhased it works fine, I think the problem lies with the password verify part.
Im just unsure where to place it if someone could guide me in the right direction that will be amazing...
So the issue is when I send the $password example test5 it only reads as test 5 and not this $2y$10$viov5WbMukXsCAfIJUTUZetGrhKE9rXW.mAH5F7m1iYGfxyQzQwD.
This was the original Code
<?php
include("dbconnect.php");
/////// First Function To Get User Data For Login
if($_GET["stuff"]=="login"){
$mysqli = new mysqli($DB_host, $DB_user, $DB_pass, $DB_name);
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/////// Need to Grab Username And Password
$username = $_GET["user"];
$password = $_GET["password"];
$query = "SELECT username, password, regkey, banned FROM users WHERE username='$username' and password='$password'";
if ($stmt = $mysqli->prepare($query)) {
$stmt->execute();
$stmt->bind_result($username, $password, $regkey, $banned);
while ($stmt->fetch()) {
echo "{";
echo '"result": "success",';
echo '"regkey": "' . $regkey . '",';
echo '"banned": "' . $banned . '"';
echo "}";
}
$stmt->close();
}
$mysqli->close();
}
Then I tried This
<?php
include("dbconnect.php");
/////// First Function To Get User Data For Login
if($_GET["stuff"]=="login"){
$mysqli = new mysqli($DB_host, $DB_user, $DB_pass, $DB_name);
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/////// Need to Grab Username And Password
$username = $_GET["user"];
$password = $_GET["password"];
$GetPassword = "SELECT password FROM users WHERE username='$username'";
$data = mysqli_query($GetPassword);
if(password_verify($password, $data['password'])) {
$query = "SELECT username, password, regkey, banned FROM users WHERE username='$username' and password='$password'";
if ($stmt = $mysqli->prepare($query)) {
$stmt->execute();
$stmt->bind_result($username, $password, $regkey, $banned);
while ($stmt->fetch()) {
echo "{";
echo '"result": "success",';
echo '"regkey": "' . $regkey . '",';
echo '"banned": "' . $banned . '"';
echo "}";
}
$stmt->close();
}
} else {
// password is in-correct
}
$mysqli->close();
}
$data = mysqli_query($GetPassword);
^^^---mysqli result handle/object
if(password_verify($password, $data['password'])) {
^^^^^^^^^^^^---no such element in mysqli
You never fetched your data results, so you're comparing the entered password against a non-existent element of the $data result object/handle.
You need
$row = mysqli_fetch_assoc($data);
password_verify(..., $row['password']);
Most likely you're running with error_reporting and display_errors disabled, meaning you'd never see the "undefined index" warnings that PHP would ave been throwing everytime you ran this code. Those settings should NEVER be off on a devel/debug system.
And note that you're vulnerable to sql injection attacks, so your "security" system is anything but -it's entirely useless and trivially bypassable.
There are several issues with your code, such as:
This statement $data = mysqli_query($GetPassword) is wrong. mysqli_query() expects first argument to be your connection handler, so it should be,
$data = mysqli_query($mysqli, $GetPassword);
Look at this statement, if(password_verify($password, $data['password'])) { ...
mysqli_query(), on success, returns a result set, so you can't get the password using $data['password']. First fetch the row from the result set and then get the password, like this,
$row = mysqli_fetch_assoc($data);
if(password_verify($password, $row['password'])) { ...
Look at the following query,
$query = "SELECT username, password, regkey, banned FROM users WHERE username='$username' and password='$password'";
This query won't return any rows because of this WHERE condition, ...password='$password'. So the solution is, instead using two separate queries, use only one query to validate the password and retrieve relevant data. The solution is given down below.
Your queries are susceptible to SQL injection. Always prepare, bind and execute your queries to prevent any kind of SQL injection.
If you want to build a json string then instead of doing echo "{"; echo '"result": "success",'; ..., create an array comprising of all the relevant data and then json_encode the array.
So the solution would be like this:
// your code
$username = $_GET["user"];
$password = $_GET["password"];
// create a prepared statement
$stmt = mysqli_prepare($mysqli, "SELECT username, password, regkey, banned FROM users WHERE username=?");
// bind parameters
mysqli_stmt_bind_param($stmt, 's', $username);
// execute query
mysqli_stmt_execute($stmt);
// store result
mysqli_stmt_store_result($stmt);
// check whether the SELECT query returned any row or not
if(mysqli_stmt_num_rows($stmt)){
// bind result variables
mysqli_stmt_bind_result($stmt, $username, $hashed_password, $regkey, $banned);
// fetch value
mysqli_stmt_fetch($stmt);
if(password_verify($password, $hashed_password)){
echo json_encode(array('result' => 'success', 'regkey' => $regkey, 'banned' => $banned));
}else{
// incorrect password
}
}else{
// no results found
}
mysqli_stmt_close($stmt);
// your code
I'm a beginner in php and I want to check if the username entered already exists.
Here is my code.
<?php
ini_set('display_errors',1);
error_reporting(E_ALL);
if (isset($_POST['submit'])) {
include "connect.php";
ValidateUser();
}
function ValidateUser()
{
if (!empty($_POST['username']) AND !empty($_POST['password'])) {
$queryrow=mysqli_query("SELECT * FROM websiteusers WHERE username = '$_POST['username']'");
if ($rows=mysqli_num_rows($queryrow)=0) {
RegisterUser();
}
}
function RegisterUser() {
echo "works up to here";
}
?>
It doesn't even give me an error despite turning error reporting on.
Have you even initialized a mysqli_connect?
$Connection = mysqli_connect("host","user","pass","database");
Then pass it to a function which uses mysqli_query() by:
function foo ($DB){
mysqli_query($DB,"QUERY HERE");
// Do other stuff
return /* Whatever you wish to return here*/
}
foo($Connection);
What you are trying to achieve can be done very easily with the following code. A bigger concern is security. It is good practice to both sanitize your input every time the user has a chance to input text.
Also, using prepared query's will put yet another layer of security.
Although this isn't using your provided code directly, I believe it is good to teach good habits.
If you have any questions feel free to ask.
$username = $_POST['username']; <-- sanitize this
$message = null;
$mysqli = new mysqli("localhost", "user", "password", "database");
$stmt = $mysqli->prepare("SELECT username FROM websiteusers WHERE username=?");
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($usernamesql);
$stmt->fetch();
if ($stmt->num_rows() > 0) {
RegisterUser();
} else {
$message .= 'username already exists';
}
Later on when you require more items to be queried, or more results to be bound:
$stmt = $mysqli->prepare("SELECT username,password,other1,other2 FROM websiteusers WHERE username=?");
$stmt->bind_param('s', $username); <-- the "s" means the argument is a strings, if a argument is stored as an int use "i", but one character for each argument is required.
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($usernamesql);
$stmt->fetch();
Multiple Arguments:
$stmt = $mysqli->prepare("SELECT username,password,other1,other2 FROM websiteusers WHERE username=? AND authenticated=?");
$stmt->bind_param('si', $username,$isauthenticated); <-- second argument is a INT or BOOL
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($usernamesql,$passwordsql,$other1sql,$other2sql);
$stmt->fetch();
When your expecting multiple results, and lets say you want to dump them into arrays:
$userarray = array();
$stmt = $mysqli->prepare("SELECT username FROM websiteusers WHERE username=?");
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($usernamesql);
while($stmt->fetch()){
array_push($userarray, $usernamesql);
}
$userarray is now an array of all the results fetched from the database.
Here is the right way to do this:
<?php
ini_set('display_errors',1);
error_reporting(E_ALL);
if (isset($_POST['submit'])) {
$mysqli = new mysqli("localhost", "user", "password", "database");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
if(check_user($mysqli, $_POST['username']){
registerUser();
}else{
echo 'user exist, cannot register';
}
}
function check_user($conn, $username){
$query = "SELECT * FROM websiteusers WHERE username = ?";
if ($stmt = $conn->prepare($query)) {
$stmt->bind_param("s", $username);
$stmt->execute();
$stmt->close();
}
return $stmt->num_rows === 0;
}
function registerUser() {
echo "registering user ...";
}
Read up on prepared statement
I have PHP + AS3 user login®ister modul.I want to check registered user by username.But can't do it because I'm new at PHP.If you can help it will helpfull thx.(result_message part is my AS3 info text box.)
<?php
include_once("connect.php");
$username = $_POST['username'];
$password = $_POST['password'];
$userbio = $_POST['userbio'];
$sql = "INSERT INTO users (username, password, user_bio) VALUES ('$username', '$password', '$userbio')";
mysql_query($sql) or exit("result_message=Error");
exit("result_message=success.");
?>
Use MySQLi as your PHP function. Start there, it's safer.
Connect your DB -
$host = "////";
$user = "////";
$pass = "////";
$dbName = "////";
$db = new mysqli($host, $user, $pass, $dbName);
if($db->connect_errno){
echo "Failed to connect to MySQL: " .
$db->connect_errno . "<br>";
}
If you are getting the information from the form -
$username = $_POST['username'];
$password = $_POST['password'];
$userbio = $_POST['userbio'];
you can query the DB and check the username and password -
$query = "SELECT * FROM users WHERE username = '$username'";
$result = $db->query($query);
If you get something back -
if($result) {
//CHECK PASSWORD TO VERIFY
} else {
echo "No user found.";
}
then verify the password. You could also attempt to verify the username and password at the same time in your MySQL query like so -
$query = "SELECT * FROM users WHERE username = '$username' AND password = '$password';
#Brad is right, though. You should take a little more precaution when writing this as it is easily susceptible to hacks. This is a pretty good starter guide - http://codular.com/php-mysqli
Using PDO is a good start, your connect.php should include something like the following:
try {
$db = new PDO('mysql:host=host','dbname=name','mysql_username','mysql_password');
catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
Your insert would go something like:
$username = $_POST['username'];
$password = $_POST['password'];
$userbio = $_POST['userbio'];
$sql = "INSERT INTO users (username, password, user_bio) VALUES (?, ?, ?)";
$std = $db->prepare($sql);
$std = execute(array($username, $password, $userbio));
To find a user you could query similarly setting your $username manually of from $_POST:
$query = "SELECT * FROM users WHERE username = ?";
$std = $db->prepare($query)
$std = execute($username);
$result = $std->fetchAll();
if($result) {
foreach ($result as $user) { print_r($user); }
} else { echo "No Users found."; }
It is important to bind your values, yet another guide for reference, since I do not have enough rep yet to link for each PDO command directly from the manual, this guide and website has helped me out a lot with PHP and PDO.