I'm building a restricted area but I have some problems with password authentication. The system doesn't recognize the password stored into database
step by step. New user:
$userName = $_POST['txtUserName'];
$password = $_POST['txtPassword'];
$sql = "INSERT INTO tbl_user (user_name, user_password, user_regdate)
VALUES ('$userName', PASSWORD('$password'), NOW())";
This works. I have a new user stored into database
Database: MySQL V5.6
`user_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_name` varchar(20) NOT NULL DEFAULT '',
`user_password` varchar(32) NOT NULL DEFAULT '',
ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ;
So I try to login (from login form):
// if we found an error save the error message in this variable
$errorMessage = '';
$userName = $_POST['txtUserName'];
$password = $_POST['txtPassword'];
// first, make sure the username & password are not empty
if ($userName == '') {
$errorMessage = 'You must enter your User Name';
} else if ($password == '') {
$errorMessage = 'You must enter your password';
} else {
// check the database and see if the username and password combo do match
$sql = "SELECT user_id
FROM tbl_user
WHERE user_name = '$userName' AND user_password = PASSWORD('$password')";
$result = dbQuery($sql);
if (dbNumRows($result) == 1) {
$row = dbFetchAssoc($result);
$_SESSION['plaincart_user_id'] = $row['user_id'];
// log the time when the user last login
$sql = "UPDATE tbl_user
SET user_last_login = NOW()
WHERE user_id = '{$row['user_id']}'";
dbQuery($sql);
// now that the user is verified we move on to the next page
// if the user had been in the admin pages before we move to
// the last page visited
if (isset($_SESSION['login_return_url'])) {
header('Location: ' . $_SESSION['login_return_url']);
exit;
} else {
header('Location: index.php');
exit;
}
} else {
$errorMessage = 'Username or password wrong';
}
}
return $errorMessage;
}
It seems that doesn't recognize the password function (), because if I write manually in the database password fiels a value not encrypted, it works...
You're using MySQL's PASSWORD function for a use it's not intended for. Aside from being a horrible idea from a security standpoint (plaintext passwords can end up in the logs), it also means that MySQL will silently truncate the password if the password field isn't long enough for it. This will results in password hashes that can never match.
You need to look into password hashing to make your passwords more secure and less prone to truncation errors (DO NOT USE MD5 OR SHA-1 FOR THIS! Even SHA-256 is dubious). You also need to determine how long a hash string will be for the method you've chosen and make sure the password field is big enough to take it.
http://php.net/manual/en/book.password.php
Related
I'm trying to hash the users password using md5 but I can't log in. It store the password hashed but when I do the login it doesn't work.Why? These are the functions (before I started using md5 it worked)
function checkLogin($username, $password)
{
$password=md5($password);
$checkLogin = "select * from users where username='$username' AND password='$password'";
$check = mysql_query($checkLogin);
return mysql_num_rows($check) > 0 ? true : false;
}
function setRegistration($username, $password) {
$query = "insert into users (username, password) values('$username' , md5('$password'))";
mysql_query($query)
or die (mysql_error());
}
This is because during registration you are converting the password to MD5 through SQL and during login you are comparing the password converted to MD5 by php.
That is why they are mismatching I guess this is not the case on all servers.
But sometime It cause problems.
So the better approach is to convert password through PHP or by SQL during both sign_up and sign_in
Because In case of php use may like to add some salt values in their MD5 string
I found the mistake.
Column password was varchar(10) instead of varchar(32) (thank you for telling me that!)
When I was trying to resolve the problem I wrote that :
$check = $Database->checkLogin($_POST['username'], md5($_POST['password']));
and then in the database function
function checkLogin($username, $password)
{
$password=md5($password);
$checkLogin = "select * from users where username='$username' AND password='$password'";
$check = mysql_query($checkLogin);
return mysql_num_rows($check) > 0 ? true : false;
}
So I was basically doing an hash of a already hashed password!
You need to correct your Insert Query like this.
$query = "insert into users (username, password) values('$username' , '".md5($pass)."')";
This question already has answers here:
Secure hash and salt for PHP passwords
(14 answers)
Closed 7 years ago.
I am making a registration page and I used sha1() to encrypt my passwords upon registration. I check my tables and the passwords are encrypted but when I try logging in, the password is considered invalid. I was wondering if someone could check the login code for it? I am aware that sha1() is unsuitable for password encryption but I haven't learnt better encryption methods yet and this is considered enough for our assignment.
Registration code:
<?php
if (!empty($_POST) && !empty($_POST['username']) && !empty($_POST['password']) && !empty($_POST['email'])) {
$username = strip_tags($_POST['username']);
$password = strip_tags($_POST['password']);
$email = strip_tags($_POST['email']);
$username = mysqli_real_escape_string($db, $username);
$password = mysqli_real_escape_string($db, $password);
$email = mysqli_real_escape_string($db, $email);
$passwordhash = sha1($_POST["password"]);
$query = "SELECT COUNT(*) AS count FROM login_details WHERE Username = '".$username."'";
$result = $db->query($query);
$data = $result->fetch_assoc();
if ($data['count'] > 0) {
echo "<p>Username taken!</p>";
} else {
$query = "INSERT INTO login_details (Username, Password, Email) VALUES ('".$username."','".$passwordhash."','".$email."')";
$result = $db->query($query);
$query = "INSERT INTO authors (Name) VALUES ('".$username."')";
$result = $db->query($query);
$query = "INSERT INTO `login_profile` (`user_id`, `author_id`) SELECT `login_details`.`id`, `authors`.`id` FROM `login_details`, `authors` WHERE `login_details`.`Username` = '".$username."' AND `authors`.`Name` = '".$username."'";
$result = $db->query($query);
if ($result) {
echo "<p>User registered!</p>";
} else {
echo "SQL Error: " . $db->error;
}
}
}
?>
Thank you!
This should be a comment, but its a bit long....
There are some problems here.
Why are you escaping the password before hashing it? It won't affect the outcome as long as you do the same thing when you try to validate the password.
You should be using a salt for the hash, ideally a random value. There are already several comments suggesting that sha1 is "not good enough" but in the absence of a salt there is little difference between md5, sha1, sha256, sha3-512...
And why check if the user exists before attempting to insert? If you have configured your table correctly, it will throw a duplicate key error if you try to create a username which already exists.
Storing the sane data in 2 different places and maintains a mapping in a third is just silly.
As to why the code you haven't shown us is not working....afraid my crystal ball is on the blink.
I am making a site where you need to register and then create a character to play with.
How i can combine the tables i use from the register page with a table for the player, so that a player always gets his created character.
i have a table members that is user to store the registered users
and a table players for the characters
i looked into the session_id but from what i understand i cant store data into a mysql table with that.
i also looked into adding the username and email from the members table to the players table on creation but i failed to so. i was thinking i could the say if username and ID are the same in both tables user that player.
i am very new at all of this.
this is the register code
<?php
include_once 'db_connect.php';
include_once 'psl-config.php';
$error_msg = "";
$now = time();
if (isset($_POST['username'], $_POST['email'], $_POST['p'])) {
// Sanitize and validate the data passed in
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$email = filter_var($email, FILTER_VALIDATE_EMAIL);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
// Not a valid email
$error_msg .= '<p class="error">The email address you entered is not valid</p>';
}
$password = filter_input(INPUT_POST, 'p', FILTER_SANITIZE_STRING);
if (strlen($password) != 128) {
// The hashed pwd should be 128 characters long.
// If it's not, something really odd has happened
$error_msg .= '<p class="error">Invalid password configuration.</p>';
}
// Username validity and password validity have been checked client side.
// This should should be adequate as nobody gains any advantage from
// breaking these rules.
//
$prep_stmt = "SELECT id FROM members WHERE email = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
// check existing email
if ($stmt) {
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// A user with this email address already exists
$error_msg .= '<p class="error">A user with this email address already exists.</p>';
$stmt->close();
}
$stmt->close();
} else {
$error_msg .= '<p class="error">Database error Line 39</p>';
$stmt->close();
}
// check existing username
$prep_stmt = "SELECT id FROM members WHERE username = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
if ($stmt) {
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// A user with this username already exists
$error_msg .= '<p class="error">A user with this username already exists</p>';
$stmt->close();
}
$stmt->close();
} else {
$error_msg .= '<p class="error">Database error line 55</p>';
$stmt->close();
}
// TODO:
// We'll also have to account for the situation where the user doesn't have
// rights to do registration, by checking what type of user is attempting to
// perform the operation.
if (empty($error_msg)) {
// Create a random salt
//$random_salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE)); // Did not work
$random_salt = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true));
// Create salted password
$password = hash('sha512', $password . $random_salt);
// Insert the new user into the database
// Add here wat you want to add into the database at account creation
if ($insert_stmt = $mysqli->prepare("INSERT INTO members (username, email, password, salt, accdate) VALUES (?, ?, ?, ?, now())")) {
$insert_stmt->bind_param('ssss', $username, $email, $password, $random_salt);
// Execute the prepared query.
if (! $insert_stmt->execute()) {
header('Location: ../error.php?err=Registration failure: INSERT');
}
}
header('Location: ./register_success.php');
}
}
can anyone point me in the right direction?
Thanks
That's a lot to read, generally speaking though you would want to associate the user id on the user table with the character. ( user_id would be a foreign key on characters pointing to id on user table. both tables have a primary key of id which should be auto incremented ), you do then have to maintain the relationship so when they create the character you could insert the current logged in user_id into the table, if you want to limit them to one character you can make the column ( user_id ) unique.
for example ...
table user,
id, name, login, password etc...
table character
id, user_id, character_name, hp, etc..
then you can join on the tables like so
SELECT u.*, c.* FROM users AS u JOIN characters AS c ON u.id = c.user_id WHERE u.id = $user_id.
that would ( in theory ) give you all the records from the users table and characters table for the $user_id ( assuming they have records in both tables, use LEFT JOIN, if they don't or may not have a character record )
HERE is a good tutorial on some basic database relationships.
http://code.tutsplus.com/articles/sql-for-beginners-part-3-database-relationships--net-8561
I'm building a website where users log in and then are redirected to another page. I want to display their usernames and profile pictures in the top bar, but my code doesn't work.
I use the code below, which now that I think of it obviously couldn't work, bacause it will always display the first username and picture in the database. But I don't know how to fix that so that it displays the username and picture of the user who have logged in.
HTML and PHP
<?php
mysql_select_db($database_connection, $connection);
$query_user = "SELECT username, profilepic FROM user";
$user = mysql_query($query_user, $connection) or die(mysql_error());
$row_user = mysql_fetch_assoc($user);
$totalRows_user = mysql_num_rows($user);
?>
<div id="top">
<img src="images/<?php echo $row_user['profilepic']; ?>">
<?php echo $row_user['username']; ?></a>
</div>
EDIT
Login script
<?php
if (isset($_REQUEST['login'])){
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
$query = "SELECT * FROM `username` WHERE username='$username' and password='$password'";
$result = mysql_query($query) or die(mysql_error());
$count = mysql_num_rows($result);
if ($count == 1){
$_SESSION['username'] = $username;
header('Location: content.php');
}else{
echo "Invalid Login Credentials.";
}
}
if (isset($_SESSION['username'])){
$username = $_SESSION['username'];
header('Location: content.php');
}
?>
store the usename in session after login code like this
<?php
session_start();
.......
//your php login code which validates the username and password ...
.......
//then here
$_SESSION['valid_user']=$username;//$username is who is logged in
now in the above use this session value like this
session_start();
$query_user = "SELECT username, profilepic FROM user where username=".$_SESSION['valid_user'];//or
$user = mysql_query($query_user, $connection) or die(mysql_error());
$row_user = mysql_fetch_assoc($user);
$totalRows_user = mysql_num_rows($user);
HTTP is a stateless protocol.
That means (for our discussion) that the server doesn't know that you are the same guy who logged in in the previous transaction he handled. Therefore you need to identify yourself each time.
This is accomplished with sessions. Session identifier is a unique string that identifies a specific client. In every request the client makes the session identifier is included either as a GET, POST or COOKIE variable.
It is unproductive and dangerous to send each and every time the user name and password to the server. What you should do instead is:
Check the username and password that the user sends to your php script. If the credentials are correct execute
session_start();
Then you should store the session identifier (which is a random string) returned from
session_id();
in a database table that has two columns. The first column is for your random string and the second for storing the primary key value of the row from your users table that holds the data of the user that sent you his credentials. An script that would do that is:
$userResult = mysql_query('select id from users where binary userName = \''.
mysql_real_escape_string($_POST['userName']) .'\' and binary passWord= \''.
mysql_real_escape_string($_POST['passWord']) .'\'');
if (mysql_num_rows($userResult))
{
start_session();
$userId = mysql_fetch_row($userResult);
mysql_query('insert into sessions (sessionId, userId) values (\''.
mysql_real_escape_string(session_id()) .'\', \''. (int)$userId[0] .'\')');
}else
{
//handle user supplying bad username or password
}
Each time the user sends a request you should find out who he is:
session_start();
$inputSessionIdentifier = mysql_real_escape_string(session_id());
$result = mysql_query('select * from sessions where sessionId = \''.
$inputSessionIdentifier .'\'');
if (mysql_num_rows($result))
{
// user is already logged in, lets find out his data
$sessionData = mysql_fetch_assoc($result);
$userResult = mysql_query('select * from users where id=\''.
mysql_real_escape_string($sessionData['userId']) .'\'');
$userData = mysql_fetch_assoc($userResult);
echo 'Hello '. $userData['userName'];
}else
{
//user is not logged in, ask for credentials or whatever ...
}
an example definition of the sessions table could be :
create table sessions ( sessionId varchar(255) not null,
userId int(10) unsigned not null,
unique(sessionId));
assuming that your users table has an unsigned integer primary key and is defined along the lines of :
create table users (id int(10) unsigned not null auto_increment primary key,
userName varchar(16) not null,
passWord varchar(100) not null,
unique(userName));
Have in mind that sessions must expire and the relevant table should be purged of inactive sessions. That means that a real life script would be a tad more complex...
IMPORTANT SECURITY ISSUE!
The sample above assumes that you are storing plain text passwords in your database. This is WRONG and a very poor security practice. Passwords should always be stored in an encrypted (hashed) form preferably the one generated by the blowfish cypher.
I'm new to mysql and php.
Been working on creating a database with a table for users.
I've managed to successfully add users to the database, and their passwords with md5(yea i know it's not secure), it's not going to be launched online.
My problem is, how do I log a user in, based on their correct username and password.
here is my code
My logic is taht after the query runs, it will return either true or false.
If true, then display successful login, else unsuccessful.
however, even if i input a correct username and password, i still get a unsuccessful login message
i checked the mysql database, and the uesrname is in there correctly
ideas?
if(!empty($_POST['userLog']) && !empty($_POST['passLog']))
{
//set the username and password variables from the form
$username = $_POST['userLog'];
$password = $_POST['passLog'];
//create sql string to retrieve the string from the database table "users"
$sql = "SELECT * FROM `users` WHERE userName = '$username' AND password = md5('$password')";
$result = mysql_query($sql);
if ($result == true) {
$return = "<font color=#008000><Center><b>**Successful Login**</b></Center></font>";
} else {
$return = "<font color=#ff0000><Center><b>**Failed Login**</b></Center></font>";
}
print($return);
}
I'm not entirely sure your SQL will run, but just to be on the safe side.
Change it so that
$password_hash = md5($password);
$sql = "SELECT * FROM `users` WHERE userName = '$username' AND password = '$password_hash'";
And for your original question
if(mysql_num_rows($result) == 1) { //If the SQL returns one row, that means that a user was found with `userName = $username` and `password = md5($password)`
// Login
} else {
// Authentication Failed
}
Also, consider using MySQLi instead of MySQL since it has been depreciated.
First of all, protect your code against SQL injections.
Then, make sure that the password in the DB is really hashed with md5() function.
Make sure you form uses POST method to pass the data to the script.
Try the following code:
if(!empty($_POST['userLog']) && !empty($_POST['passLog']))
{
//set the username and password variables from the form
$username = $_POST['userLog'];
$password = $_POST['passLog'];
//create sql string to retrieve the string from the database table "users"
$sql = "SELECT * FROM `users` WHERE userName = '". addslashes($username) ."' AND password = '". md5('$password')."'";
$result = mysql_query($sql);
if (mysql_num_rows($result)>0) {
$return = "<font color=#008000><Center><b>**Successful Login**</b></Center></font>";
} else {
$return = "<font color=#ff0000><Center><b>**Failed Login**</b></Center></font>";
}
print($return);
}
mysql_query doesn't return TRUE or FALSE. Per the docs (http://php.net/manual/en/function.mysql-query.php), it returns a resource if successful, or FALSE if there is an error. You need to evaluate the resource to see if it's valid.
if(!empty($_POST['userLog']) && !empty($_POST['passLog']))
{
//set the username and password variables from the form
$username = $_POST['userLog'];
$password = $_POST['passLog'];
//create sql string to retrieve the string from the database table "users"
$sql = "SELECT * FROM `users` WHERE userName = '$username' AND password = md5('$password')";
$result = mysql_query($sql);
if ($result && $row = mysql_fetch_assoc($result)) {
$return = "<font color=#008000><Center><b>**Successful Login**</b></Center></font>";
} else {
$return = "<font color=#ff0000><Center><b>**Failed Login**</b></Center></font>";
}
print($return);
}
As mentioned in my comment, the issue seems to be your sql string. Instead of hashing, you are putting the method into the string. So change
$sql = "SELECT * FROM `users` WHERE userName = '$username' AND password = md5('$password')";
to
$sql = "SELECT * FROM `users` WHERE userName ='$username' AND password = '".md5('$password')."'";
Your result will not be true or false, but since php treats any value not a 0 as true, it will work as is.
Also, it is strongly recommended to escape all data going into your sql string to prevent sql injection. Another note: mysql is being deprecated, so now would be a great time to move to something like mysqli.