This register form was made by me, but it doesn't do what I want it to do.
I want it to connect to a mysql database and store the information that was given by the form. I want it to hash the $password in md5 and store it in the "gebruikers" table. Please don't reply with "Damn, you have no idea what you are doing" or something like that. I am learning PHP by looking to examples and following tutorials. Please keep in mind that the mysql insert code is not filled in right, because I got stuck a few lines above.
So, my question is: I want to check if the mysql table already contains $email. If it IS already in the mysql table, I want to display an error message that I can place somewhere else in my PHP page. If the email adress given is unique, than the $password should hash into md5 and store into the mysql database, just like the other form entries.
How do I do that?
<?php
// Fetching all the form details
$email = $_POST["email"];
$password = $_POST["password"];
$voornaam = $_POST["voornaam"];
$tussenvoegsel = $_POST["tussenvoegsel"];
$achternaam = $_POST["achternaam"];
$dag = $_POST["dag"];
$maand = $_POST["maand"];
$jaar = $_POST["voornaam"];
$straat = $_POST["straat"];
$postcode = $_POST["postcode"];
$woonplaats = $_POST["woonplaats"];
$cniveau = $_POST["cniveau"];
$oniveau = $_POST["oniveau"];
$voornaam = $_POST["voornaam"];
$aboutme = $_POST["aboutme"];
//Here's where I don't know how to continue
$check = mysql_query("SELECT * FROM `gebruikers` WHERE `email` = '$email'");
if($check === FALSE) {
//there is a user already registered
echo("$email is al in gebruik. <a href='login.php'>Inloggen</a>?");
} else {
//There isn't a username
//mysql_query("INSERT INTO `user` (`id` ,`username` ,`password`) VALUES (NULL , '{$_POST['email']}', MD5( '{$_POST['password']}' ))");
echo("You have been registered!");
}
P.S.: I'm not a native English speaker, so please ignore my grammar mistakes/typos.
First of all, you made a major mistake: There is a SQL-Injection security hole.
Please read this: http://php.net/manual/en/security.database.sql-injection.php
Second, you should use mysqli instead of mysql, because mysql is deprecated.
Your error is that SQL does only return false if the query is invalid, not if there are no results. So the correct way of checking if there are results is to use http://php.net/manual/en/mysqli-result.num-rows.php
$result = mysql_query("SELECT * FROM `gebruikers` WHERE `email` = '$email' LIMIT 1");
if(mysql_fetch_array($result) !== false)
{
...
} else {
....
}
You should also read up on preventing SQL injection.
Maybe you've forgot to set the mysql_connect statement.
But I strongly recommend you stick from now on, with the mysqli_ functionality, since, as Aragon0 said, mysql is deprecated in PHP's newest versions.
Besides, mysqli statements are simpler than the mysql ones, for example you use one statement (mysqli_connect) to connect to your host and select your database at the same time, instead of using separated statements (both mysql_connect and mysql_select_db).
Oh, and no additional service package is required to use it. :)
Related
I hope I formatted the code properly. I am having trouble making this if statement to work. I've searched and from what it looks like this statement should work. However, when I run it no matter the password if the username starts with kacey then it goes to echo "Logged in as: " . kacey;
Likewise, if I put the input to kaceyfeewaf, it still goes to echo "Logged in as: " . $myuser; This happens regardless of the password I put in. the line $result['username'] should validate to KACEY.
$sql = "SELECT * FROM $dbTable WHERE username = $myuser AND password = $mypass";
$result = mysql_query($sql);
if($result['username'] = $myuser && $result['password'] = $mypass;)
{
echo "Logged in as: " . $myuser;
} else {
echo "Fail ";
}
There are a few issues here.
Firstly, the variables you have in your query are strings, therefore they require to be quoted:
WHERE username = '$myuser' AND password = '$mypass'
Having or die(mysql_error()) to mysql_query() would have signaled the syntax error.
Then you're assigning instead of comparing with
if($result['username'] = $myuser && $result['password'] = $mypass;)
use two equals ==
However, that isn't how you check if those rows exist.
You need to use mysql_num_rows() or use a while loop while using a function to fetch/iterate over results found.
Here is an MySQLi example using mysqli_num_rows():
$conn=mysqli_connect("hostname","username","password","db");
$check_select = mysqli_query($conn, "SELECT * FROM `users`
WHERE email = '$email' AND pw='$pass'");
$numrows=mysqli_num_rows($check_select);
if($numrows > 0){
// do something
}
Now, we don't know where those variables have been assigned, and if from a form that it's using a POST method with matching name attributes.
I.e.:
<form action="" method="post">
<input type="text" name="username">
...
</form>
$username = $_POST['username'];
Another thing which is unknown to us is the MySQL API you're using to connect with. Make sure that you are indeed using the same one as you are using to query with, being mysql_. Different APIs do not intermix, such as mysqli_ or PDO. Use the same one from connection to querying.
Add error reporting to the top of your file(s) which will help find errors.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
// rest of your code
Sidenote: Displaying errors should only be done in staging, and never production.
I noticed you may be storing passwords in plain text. If this is the case, it is highly discouraged.
I recommend you use CRYPT_BLOWFISH or PHP 5.5's password_hash() function. For PHP < 5.5 use the password_hash() compatibility pack.
Here is a PDO solution pulled from one of ircmaxell's answers:
https://stackoverflow.com/a/29778421/
Just use a library. Seriously. They exist for a reason.
PHP 5.5+: use password_hash()
PHP 5.3.7+: use password-compat (a compatibility pack for above)
All others: use phpass
Don't do it yourself. If you're creating your own salt, YOU'RE DOING IT WRONG. You should be using a library that handles that for you.
$dbh = new PDO(...);
$username = $_POST["username"];
$email = $_POST["email"];
$password = $_POST["password"];
$hash = password_hash($password, PASSWORD_DEFAULT);
$stmt = $dbh->prepare("insert into users set username=?, email=?, password=?");
$stmt->execute([$username, $email, $hash]);
And on login:
$sql = "SELECT * FROM users WHERE username = ?";
$stmt = $dbh->prepare($sql);
$result = $stmt->execute([$_POST['username']]);
$users = $result->fetchAll();
if (isset($users[0]) {
if (password_verify($_POST['password'], $users[0]->password) {
// valid login
} else {
// invalid password
}
} else {
// invalid username
}
You should use == instead of simple = for your if condition
First of all delete that if stmt and make new one where you check for num rows. If there is num rows > 0 you have valid login. And then print needed results from database od current query.
Edit:
You have = insted of == or === so stmt is always true.
Plenty of time, spent, here is where I'm at:
$uname_query = mysql_query("SELECT username FROM blog_members WHERE username='".$username."'");
if ($uname_query == $username) {
$error[] = 'Username is already taken';
}
I'm trying to use the SQL query $uname_query to pull the $username entered in a form, if it exists, then use an if statement to display the error, if it exists.
As it is coded right now, I get no error but also no functionality.
What am I missing?
You need to use a fetch.
$row = mysql_fetch_row($uname_query);
// $row[0] will contain the first column of the first row (username)
if ($row[0] == $username) { }
However, you should look at using PDO or MySQLi since the MySQL api is deprecated. You should also use prepared statements if $username is provided by the user.
In PDO you could do:
$stmt = $pdo->prepare("SELECT username FROM blog_members WHERE username=?");
$stmt->execute(array($username));
// fetchColumn will return the first column of the first row (username)
if ($stmt->fetchColumn() == $username) { }
This protects against SQL injections by providing a prepared statement without $username and binding it in the execute() function. PDO requires some different setup initially too, but here is a good tutorial: http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers
You have to fetch the data before compare as
$row = mysql_fetch_array( $uname_query);
if($row["username"] == $username){
$error[] = 'Username is already taken';
}
You need to fetch the data from the query first.
$uname_query = mysql_query("SELECT username FROM blog_members WHERE username='".$username."'");
$arr=mysql_fetch_array($uname_query);
if ($arr["username"] == $username) {
$error[] = 'Username is already taken';
}
For one, you need to fetch it. Use mysql_fetch_row(). Secondly, I'm not sure what that $error[]='string' business is. Are you trying to use an array?
Although I suggest moving to mysqli since mysql is deprecated. Also, I hope you sanitized that string well.
I'd like to make an if statement that checks if the username, already exists in the MYSQL database. I tried some different stuff, but i cant make it work. Every time I test it in my browser I get a notice
Notice: Undefined index: username in etc.
I am confused if it has anything to do with the $result variable or the $check variable or neither.
Here is the HTML form and the PHP script.
https://gist.github.com/anonymous/9704354
Thank you and have a nice weekend!
There are a few things that are wrong in your code.
First, never place variables directly in SQL queries, thats how SQL injections happen. Start using PDO or another library for your MYSQL.
The reason you are getting an undefined notice is because of this line.
$result = mysql_query("SELECT * FROM users WHERE username = '$_POST[create_user]'");
It should be this without fixing the huge SQL Injection flaw
$result = mysql_query("SELECT * FROM users WHERE username = '{$_POST['create_user']}'");
Also you should add a "LIMIT 1" to the end of the select query to speed things up. No need looking for more than one user.
You can verify the user by just checking for row_count instead of checking the text values. Since MySQL is not case sensitive for some fields, username "AAAaaa" will be equal to "aaaAAA". If you check row count instead, you will be sure that no usernames are in the database of that text. Or if you want to check using PHP, make sure you pass the usernames through strtolower()
When you start using PDO, the following example will help you.
$dbh = new PDO() // Set the proper variables http://us2.php.net/pdo
if(empty($_POST['create_user'])) {
echo 'Username is Empty. Always check if POST and Get data is set';
die();
}
$query = "SELECT * FROM `users` WHERE `username` = ? LIMIT 1;"
$data = array($_POST['create_user']);
$sth = $dbh->prepare($query);
if(!$sth->execute($data)) {
echo 'Handle SQL Error';
die();
}
if($sth->rowCount() == 0) {
echo 'Unused Username';
}else{
echo 'Used Username';
}
This is what i've found
the $_POST['username'] should be like $_POST['create_user']
The code will display the returned values and and if it is greater than one it will return "Yes". But I am having trouble with the WHERE clause in $check. When I take it out the code works just fine but when I add it, the page returns incorrect values. Any ideas what's wrong?
<?php
$con = mysqli_connect("127.0.0.1","root","","lian");
$u= $_GET['username'];
$pw = $_GET['password'];
$check = "SELECT username,password FROM users WHERE username='$u' AND password='$pw'";
$login = mysqli_query($con,$check) or die(mysqli_error($con));
$num_rows = mysqli_num_rows($login);
echo "$num_rows \n";
if (mysqli_num_rows($login) == 1) {
$row = mysqli_fetch_assoc($login);
echo 'Yes';
exit;
}
else {
echo 'No';
exit;
}
Leaving aside the injection vulnerabilities, it may be because of special characters or whitespace. Try trim'ing your GET values.
$u = trim($_GET['username']);
$pwd = trim($_GET['password']);
Are you getting the number of results as 0? Also try echoing the statement in a development environment to check exactly what the statement is.
Try like this
$u= trim(mysqli_real_escape_string($_GET['username']));
$pw = trim(mysqli_real_escape_string($_GET['password']));
$check = "SELECT username,password FROM users WHERE username='$u' AND password='$pw'";
Also I hope you are ensuring unique combination of username and password.
Because suppose there are two entries in your users table
username="abc" password ="12345"
Then mysqli_num_rows() function will return two rows and the
if (mysqli_num_rows($login) == 1)
condition will return false meaning the user desn't exist.
The above comments are valid to improve the security of your code and protect vs sql injection.
Regarding your actual problem if the code executes correctly when you don't have the where clause in place but fails when you do there are a couple of possibilities:
The username or password are wrong - where wrong can mean they have extra whitespace, case insensitivities or that the column names are incorrect(case sensitive database?)
The string you are passing to the server is not displaying correctly.
Check both options by doing an echo of $u, $pw and $check right after you form your SQL string. If it's still not clear then copy whatever is echoed for $check and past it directly into the parser(management studio I guess?) and see what it returns.
Good Luck.
I can't figure out why the password isn't matching when attempting to login after activation. I've trimmed down the pasted code below for ease of viewing.
Here is the relevant registration code:
$salt = substr(sha1(uniqid(rand(),true)),0,20);
$password_db = hash('sha256', $salt.$password1);
$sqlinfo = mysql_query("INSERT INTO db_1 (email, password, salt)
VALUES('$email1','$password_db','$salt')") or die(mysql_error());
Here is the correlating code for login:
$email = $_POST['email'];
$password = $_POST['password'];
$sqlinfo = mysql_query("SELECT * FROM db_1 WHERE email='$email' AND emailactiv='1'");
if($sqlinfo['password'] == hash('sha256', $sqlinfo['salt'].$password)){
while($row = mysql_fetch_array($sqlinfo)){
... }
else { ...
I've done several iterations thus far to no avail. Any insight would be much appreciated.
you code, currently, is vulnerable with SQL injection. One suggestion is to reformat your code using PDO or MySQLI.
Example of PDO:
<?php
$stmt = $dbh->prepare("SELECT * FROM db_1 WHERE email = ? AND emailactiv=? ");
$stmt->bindParam(1, $email);
$stmt->bindParam(2, 1);
$stmt->execute();
?>
you didn't fetch the row that's why it's not matching anything.
add this line before the IF statement:
$rowHere = mysql_fetch_row($sqlinfo);
and use $rowHere in your IF statement.
$email = $_POST['email'];
$password = $_POST['password'];
$sqlinfo = mysql_query("SELECT * FROM db_1 WHERE email='$email' AND emailactiv='1'");
//You need to first fetch data before using it.
while($result = mysql_fetch_array($sqlinfo)) {
//Now you can use the data
if($result['password'] == hash('sha256', $result['salt'].$password)){
//matched... login correct
} else {
//not matched.. invalid login
}
}
...
Hope it's self-explanatory.
You missed one very important line!
BTW, stop using mysql_* functions as they are deprecated, use PDO or mysqli_*
EDIT: Please try now. I thought it can only hold one value (for login purpose)
You need to use mysqli_fetch_array.
Also, mysql_* functions are deprecated. Use MySQLi or PDO instead.
And you need to 'sanitize your inputs' (a common phrase) to avoid SQL injection, using mysqli_real_escape_string or PDO.
See the Bobby Tables link as per the comments on the question.