I'm editing part of a user login system and I'm very confused on one issue. I'm trying to allow the user to change their username using their email as a reference for the lookup. For some reason I can't get the $email variable to set properly. When I change the variable $email to an address that I know is in my database (meaning I remove $email and change it to an address that exists) the username is properly changed. When I swap it back to $email, nothing happens.
The strange part is when I echo $email, the correct email address is displayed. I can't figure out why it won't let me do this despite it being echoed properly. Is it possible to not be a string despite an email address being displayed?
I understand about sql injections. I'm just trying to keep the code as simple as possible for now so I can get the functionality working first.
<?
if (isset($_POST['submit'])) {
$email = $user->get_email($username);
$newuser = $_POST['newusername'];
$server = 'localhost';
$usern = 'root';
$pass = '';
$connection = mysql_connect($server, $usern, $pass) or die(mysql_error());
mysql_select_db(testdb, $connection) or die(mysql_error());
if(isset($username)) {
mysql_query("UPDATE users SET username='$newuser' WHERE email = '$email'") or die(mysql_error());
}
}
?>
Also, when I change the query statement so that the reference value is the userid, the username is correctly inserted. From this I know that $email isn't being set properly.
mysql_query("UPDATE users SET username='$newuser' WHERE userid = '$userid'") or die(mysql_error());
if(isset($username)) {
mysql_query("UPDATE users SET username='$newuser' WHERE email = '$email'") or die(mysql_error());
}
Where in your code are you setting the $username variable? If it's not set, your update won't run. You should probably go back and review your variable names and make sure they're consistent (and set) throughout the rest of the page.
Sounds like your get_email() function is returning a bad address.
Are you sure your authentication system is working fine in all other ways?
What happens when you do this:
echo "UPDATE users SET username='$newuser' WHERE email = '$email'";
Also, you will want to sanitize your input for $newuser to avoid SQL injection. Like one of the comments said, you should be using the user id instead of email. I am not sure what authentication class you are using, but you should be able to find something like $user->returnID() and update using that.
Anyway it's recommend to add
$email = mysql_real_escape_string($email);
Maybe that's the problem
I should use the following:
<?
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$email = $user->get_email($username); // where does $username come from anyway? and where are you initiating the $user object?
$newuser = $_POST['newusername'];
$server = 'localhost';
$usern = 'root';
$pass = '';
$connection = mysql_connect($server, $usern, $pass) or die(mysql_error());
mysql_select_db(testdb, $connection) or die(mysql_error());
if(isset($newuser)) {
$newuser = mysql_real_escape_string($newuser);
$email = mysql_real_escape_string($email);
mysql_query("UPDATE users SET username='" . $newuser . "' WHERE email = '". $email ."'") or die(mysql_error());
}
}
?>
The mysql_real_escape_string() creates a new string. It will escape characters which probably can damage your database when they are putted in. (Called: SQL Injection)
For examples of SQL Injection to give you an idea what it is, and how it can be used and protected:
http://www.unixwiz.net/techtips/sql-injection.html
Related
ok, so i have a little issue here with php. I know there are alot of similar questions, but ones i found did not help.
I dont want to use anything more like javascript or something. I got mysql set up, there are 3 columns ID username and password.
<?php
$username = $_POST['user'];
$password = $_POST['pass'];
$username = stripcslashes($username);
$password = stripcslashes($password);
$username = mysql_real_escape_string($username);
$password = mysql_real_escape_string($password);
mysql_connect("localhost","root","");
mysql_select_db("login");
$result = mysql_query("select * from users where username='$username' and password= '$password'")
or die("failed to query DB".mysql_error());
$row = mysql_fetch_array($result);
if ($row['username'] == $username && $row['password'] == $password) {header(suc.html);
die();}else{header("Location: fail.html");die();}
?>
This code, it works but when i dont fill in any details and press submit too, it gets me to the suc.html which shows successful login. Now i want to make the following:
I'll make ID's similar to each individual html's names, then the php will go match the ID number with the file name in the directory, and show the page for the respective user.
like lets say user1.
Login userlol password 123 ID user1 file user1.html
then what code to use that it goes and matches the ID user1 with the .html name, then redirects the user to their own custom page. Is there a way? Kinda getting started with php ,so cut some slack please :)
p.s i know these codes are older php codes, but anything works for me personally.
You are getting that sort of behaviour because when a username and password is not submitted, their respective values evaluates to null and your SQL query is successful but returns 0 rows thereby making your $row['username'] and $row['password'] to be null. In general, your $row['username'],$row['password'],$username,$password would all be equal to null which fulfills all the requirements to redirect to "suc.html"
To solve this problem, simply check if mysql_num_rows($result)==1 because usually, a successful login would return just one row due to unique usernames.
But
I would not advice you to continue with deprecated mysql and SQL Injection susceptible logic. Please allow me to rewrite your logic as follows:
<?php
$username = $_POST['user'];
$password = $_POST['pass'];
// You don't have to escape or sanitize user inputs if you use Prepared Statement plus sanitizing user password is highly discouraged.
// $username = stripcslashes($username);
// $password = stripcslashes($password);
// $username = mysql_real_escape_string($username);
// $password = mysql_real_escape_string($password);
// Initiate a PDO connection and set your error mode to exception.
$conn=new pdo("mysql:host=localhost;dbname=login;","root","",array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
try{
// Prepare your query and replace all values with ? which would be provided as an array in execute(); I added limit 1 to make sure we are getting a maximum of one row from our query.
$result_stmt = $conn->prepare("select * from `users` where (`username`=? and `password`=?) limit 1");
$result_stmt->execute([$username,$password]);
// fatch() would return a single row just like mysql_fetch_array or mysql_fetch_assoc while fetchAll() would return all rows.
$result=$result_stmt->fetch();
if(count($result)==1){
// There is no need to check this again because your query to the database already did.
// if ($row['username'] == $username && $row['password'] == $password)
// Redirect users to the same page but identify each user through session (recommended)
header("location:suc.html");
}else{
header("location:fail.html");
}
}catch(Exception $e){
echo $e->getMessage();
}
?>
I can't get any result from a function attempt_login() that I made myself. Can anyone figure out any errors or what is wrong with this piece of code? It worked for only one user that I created in the database. I want to get a boolean in return and afterwards wanna check if the result is true, than store it into the session and then redirect the user to a specific page. Please help!
CODE:
function attempt_login($theusername, $thepassword){
$host = 'localhost';
$username = 'root';
$password = '';
$database = 'website';
$con = mysqli_connect($host, $username, $password, $database);
$theusername = mysqli_real_escape_string($con, $theusername);
$thepassword = mysqli_real_escape_string($con, $thepassword);
$thepassword = md5($thepassword);
$query = "SELECT * FROM members WHERE username = '{$theusername}' AND password = '{$thepassword}'";
$result = mysqli_query($con, $query);
$row = mysqli_fetch_array($result);
return isset($row['name']);
mysqli_close($con);
}
SCREEN SHOT:
Let's say your password is abc'123 - you know, a good mix of letters, numbers and symbols.
mysqli_real_escape_string will transform that into abc\'123.
md5 then makes it af94b3b7388e50429710ed345b58c01c
But in the database, the password abc'123 should be encrypted as bb7e1fc94ff2a3e8d2d79c8ab055da60, which is significantly different!
Try moving the md5 call before the mysqli_real_escape_string.
EDIT: Your first user works because the password is fishman001
The second, however, is the empty string. You are probably using if( empty($_POST['password'])) or similar to see if a password was submitted. The empty string will fail this test.
PS: Rainbow tables. Love 'em. Now stop using MD5.
Is there a way to make the username part work for both upper and lower case, for example if my username were robert if you entered Robert it would work as well? Attached is a copy of my login script.
<?php
session_start();
$username = $_POST['username'];
$password = $_POST['password'];
if ($username&&$password)
{
$connect = mysql_connect("localhost","*i*****5_******","*******") or die ("Couldn't Connect"); //host,username,password
mysql_select_db("virtua15_gateway") or die ("Could not find database");
$query = mysql_query("SELECT * FROM Users WHERE username='$username'");
$numrows = mysql_num_rows($query);
if ($numrows!=0)
{
while ($row = mysql_fetch_assoc($query))
{
$dbusername = $row['username'];
$dbpassword = $row['password'];
}
if ($username==$dbusername&&md5($password)==$dbpassword)
{
header( 'Location: index2.php' );
$_SESSION['username']=$dbusername;
}
else
echo "incorrect username and password";
}
else
die ("This user does not exist");
}
else
die("Please enter a username and a password")
?>
check strtolower($username) == strtolower($dbusername)
I'm a bit confused why you're checking it twice though. You've already checked in your sql query if the usernames match. Also, are your username's not unique? Why are you doing a while loop and not just a if (false !== ($row = mysql_fetch_assoc($query)) {}
Also, you should make sure your $dbusername and $dbpassword get defined because if a row is not found, they won't be, and PHP will issue a warning about undefined variables when you access them.
Also, you should be checking if the $_POST keys are set. I tend to code a bit paranoid, but I like to make notices/warning very hard to get. If your server were set to display errors, a user could see either a rather ugly error message, or potentially even sensitive data.
Also, while I'm being way overly picky, as per the HTTP specification, the Location header expects a full URL, not just a relative file name (though all browsers support just a relative file name).
Convert to either lower/upper case or make a case insensitive match.
Important
Please don't do this:
$username = $_POST['username'];
$query = mysql_query("SELECT * FROM Users WHERE username='$username'");
As it will allow hackers to perform SQL injection! Please sanitise ALL of your inputs!
IE,
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
Important
Edit :: Also, NEVER use PHP to do the job of php
$query = mysql_query("SELECT * FROM Users WHERE username='$username'");
Is wrong, you should perform the sql query with your login logic!
IE
"SELECT * FROM Users WHERE username='$username' AND password='" . md5($password) . '"
Then you can just say this instead
if(mysql_num_rows($query)){
// Login logic
}
Edit ::
SQL queries are case insensitive
hi try strtolower() function.
$username = strtolower($_POST['username']);
Check this http://php.net/manual/en/function.strtolower.php
You can check by two tyes:
while ($row = mysql_fetch_assoc($query))
{
strtoupper($dbusername) = strtoupper($row['username']);
$dbpassword = $row['password'];
}
OR
while ($row = mysql_fetch_assoc($query))
{
strtolower($dbusername) = strtolower($row['username']);
$dbpassword = $row['password'];
}
Use any one of them.
this will resolve your problem.
A working alternative in MySQL:
mysql_query(
"SELECT * FROM Users
WHERE LOWER( username) = LOWER( '" . mysql_real_escape_string( $username) . "')"
);
If your requirement is to allow login irrespective of the case , I mean Robert, robert, ROBERT, RoBeRT etc.. , then you can consider storing the username in lowercase in the database and while retrieving convert the username to lowercase and execute the query
How can I ensure my login script is secure and make it better, This is my first code:
Help is most appreciated.
<?php
include ('../includes/db_connect.php');
$firstname = $_POST['firstname'];
$lastname = $_POST['lastname'];
$email = $_POST['email'];
$mobile = $_POST['mobile'];
$username = $_POST['username'];
$password = md5($_POST['password']);
// lets check to see if the username already exists
$checkuser = mysql_query("SELECT username FROM users WHERE username='$username'");
$username_exist = mysql_num_rows($checkuser);
if($username_exist > 0){
echo "I'm sorry but the username you specified has already been taken. Please pick another one.";
unset($username);
header("Location: /registration?registration=false");
exit();
}
// lf no errors present with the username
// use a query to insert the data into the database.
$query = "INSERT INTO users (firstname, lastname, email, mobile, username, password)
VALUES('$firstname', '$lastname','$email', '$mobile','$username', '$password')";
mysql_query($query) or die(mysql_error());
mysql_close();
echo "You have successfully Registered";
header("Location: /registration?registration=true");
// mail user their information
//$yoursite = ‘www.blahblah.com’;
//$webmaster = ‘yourname’;
//$youremail = ‘youremail’;
//
//$subject = "You have successfully registered at $yoursite...";
//$message = "Dear $firstname, you are now registered at our web site.
// To login, simply go to our web page and enter in the following details in the login form:
// Username: $username
// Password: $password
//
// Please print this information out and store it for future reference.
//
// Thanks,
// $webmaster";
//
//mail($email, $subject, $message, "From: $yoursite <$youremail>\nX-Mailer:PHP/" . phpversion());
//
//echo "Your information has been mailed to your email address.";
?>
Follow Artefacto's advice about SQL injection and Hashing passwords in the database. Other things ...
echo "I'm sorry but the username you specified has already been taken. Please pick another one.";
unset($username);
header("Location: /registration?registration=false");
Wont work because you can't echo then send a header. Headers must be sent before any output.
Also, there is no point doing this:
header("Location: /registration?registration=false");
echo "I'm sorry but the username you specified has already been taken. Please pick another one.";
unset($username);
The webbrowser will redirect straight away and the user won't see the handy message you've printed.
Also, it's usual to ask for 2 password fields on registration forms incase the user made a typo and didn't notice because all the text was *'s. You compare the 2 and if they are different you assume a typo was made and ask again.
That's not a login script. It's a registration script.
See SQL injection in the PHP manual. Your program is vulnerable to this kind of attacks.
Also, don't just or die(mysql_error()). This will expose information about your database that you may not want to expose (table names, etc.). Use proper error handling. For instance, you can throw an exception and define a uncaught exception handler that shows a "oops" page and logs the error.
Finally, use hashes strong than MD5, such as sha1.
As said by #Artefacto, that's not a login script.
But if you intend to do a login script I would like to give you a suggestion. I've done this a while ago.
Instead of doing something like this:
$sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
I would do this:
$sql = "SELECT * FROM users WHERE username = '$username'";
$user = //use the php-sql (query, fetch_row) commands to fetch the user row.
if (strcmp($user['password'], $password) == 0) {
//log in success
}
By doing this, you avoid SQL Injection in a simple and elegant way. What you guys think about it?
To reiterate what everyone else mentioned. It's important to protect yourself (and sever) from SQL injection. For example:
$checkuser = mysql_query("SELECT username FROM users WHERE username='$username'");
You're just simple taking the value from $_POST['username'] and placing it in the variable $username.
Some people aren't very nice and will try to break your program :( So it's always recommended to escape any data that was taken from a user, before placing it into an SQL query.
For instance...
This:
$checkuser = mysql_query("SELECT username FROM users WHERE username='$username'");
Becomes:
$checkuser = mysql_query("SELECT username FROM users WHERE username='" .mysql_real_escape_string($username). "'");
So recently I learned how to properly add a username and password to a database.
My database is usersys, and the table storing user information is called userdb. The table has two columns - username (primary), password.
The registration form works great, enters the users input into the database correctly and also checks to see whether the user's username is already in the database or not.
With that said, I am asking if anyone could help me create a login script. So far, this is what I have:
$username = $_POST['username'];
$password = $_POST['password'];
$displayname = $_POST['username'];
$displayname = strtolower($displayname);
$displayname = ucfirst($displayname);
echo "Your username: " . $displayname . "<br />";
mysql_connect("localhost", "root", "******") or die(mysql_error());
echo "Connected to MySQL<br />";
mysql_select_db("usersys") or die(mysql_error());
echo "Connected to Database <br />";
$lcusername = strtolower($username);
$esclcusername = mysql_real_escape_string($lcusername);
$escpassword = mysql_real_escape_string($password);
$result = mysql_query("SELECT * FROM userdb WHERE username='$esclcusername' AND password='$escpassword'") or die(mysql_error());
$row = mysql_fetch_array( $result );
$validateUser = $row['username'];
$validatePass = $row['password'];
The POST data is from the previous log in page. I want this script to check the table (userdb) and find the row for the username that the user entered from the previous form and verify that the password entered matches the username's password set in that row, in userdb table.
I also want some type of way to check whether or not if the username entered exists, to tell the user that the username entered does not exists if it can not be found in the table.
This is not a direct answer to this question but a GOOD value-add.
You should use MYSQL SHA1 function to encrypt the password before storing into the database.
$user = $_POST['userid'];
$pwd = $_POST['password'];
$insert_sql = "INSERT into USER(userid, password) VALUES($user, SHA1($pwd))";
$select_sql = "SELECT * FROM USER WHERE userid=$user AND password=SHA1($pwd))";
You can use sessions. Sessions are global variables that when set, stay with the user while he is browsing through the site.
Since you are learning PHP, try out this tutorial on the official website.
But what you would do in theory is when the username and password match, you set a session variable
$_SESSION["auth"] = true;
$_SESSION["user_id"] = $row["user_id"];
And then do a check to see if the user is authenticated.
One way to do it (DISCLAIMER: not necessarily best-practice):
$result = mysql_query("SELECT id FROM userdb WHERE username='$esclcusername' AND password='$escpassword'") or die(mysql_error());
$row = mysql_fetch_array( $result );
$id = (int)$row['id'];
if($id > 0) {
//log in the user
session_start();
$_SESSION['userId'] = $id;
$_SESSION['username'] = $displayname;
}
... and on pages that require authentication:
session_start();
if(!isset($_SESSION['userId'])) {
die('You need to be logged in!!!');
} else {
echo 'Welcome ' . $_SESSION['username'];
}
Read more about PHP sessions.
I like to use both $_SESSION and MYSQL Checks with any login POST. This should help get a few things started.
$username = mysql_real_escape_string($_POST[username]);
$password = strip_tags($_POST[password]);
$password = sha1($password);
if(isset($username) && isset($password) && !empty($username) && !empty($password))
{
$sql = mysql_query("SELECT * FROM users_column WHERE username = '$username' AND password = '$password'");
//Check the number of users against database
//with the given criteria. We're looking for 1 so
//adding > 0 (greater than zero does the trick).
$num_rows = mysql_num_rows($sql);
if($num_rows > 0){
//Lets grab and create a variable from the DB to register
//the user's session with.
$gid = mysql_query("SELECT * FROM users_column WHERE username = '$username' AND password = '$password'");
$row = mysql_fetch_assoc($gid);
$uid = $row[userid];
// This is where we register the session.
$_SESSION[valid_user] = $uid;
//Send the user to the member page. The userid is what the
//session include runs against.
header('Location: memberpage.php?userid='.$userid);
}
//If it doesn't check out -- throw an error.
else
{
echo 'Invalid Login Information';
}
}
NOTE: You would need to start the page file with session_start() and create a separate Session Check include stating with session_start() and then your progressions e.g. if($_SESSION[valid_user] != $userid) do something.
You could use a select statement to retreive from MySQL the password for the specified username. If you have an empty result set, then you do not have the username in the table.
If you need the user to be authenticated in more than one php page, then one choice whould be using sessions (http://www.php.net/manual/en/function.session-start.php).
Also, I think you should think about security, i.e. preventing SQL injection:
$variable = mysql_real_escape_string($_POST['variable'])
and avoiding to "die" (treating errors and returning user-friendly messages from the script).
I would also think about not storing passwords in your database. One way hashes with MD5 or SHA1 are a way of adding a layer of security at the db level.
See http://php.net/md5 or http://php.net/sha1 for further information.
I agree with the idea if using SESSION variables while authenticating the user.
The easy way to authenticate the user is as follows
//connect the mysql_db
$mysql_connect()
$mysql_select_db()
//reading from mysql table
$res="SELECT * FROM table WHERE name=$username AND password=$password";
$val=mysql_query($res);
//authentication
$count=mysql_num_rows($val);
if($count==1)
//authenticate the user
else
through an error