I've created a login activity and there are two edittext ids and passwords. I have a PHP code which checks the user with their id and password. If both are correct then it transfers to the other activity, but here I want a PHP code which checks the id with their specific password. If the user enters a correct id but enters an incorrect password, then it should produce an error "pls enter correct password".
Please suggest me a correct PHP code for this.
<?php
require "r_connect.php";
if($_SERVER['REQUEST_METHOD']=='POST')
{
$rollno=$_POST['rollno'];
$password=$_POST['password'];
$sql = "SELECT * FROM registration_user WHERE rollno = '$rollno' AND password='$password'";
$result = mysqli_query($connect,$sql);
$check = mysqli_fetch_array($result);
if(isset($check))
{
echo 'Success';
}
else
{
echo 'Error';
}
}
?>
Try below code for PHP:
<?php
require "r_connect.php";
if($_SERVER['REQUEST_METHOD']=='POST')
{
$rollno = $_POST['rollno'];
$password = $_POST['password'];
$sql = "SELECT password FROM registration_user WHERE rollno = '$rollno'";
$result = mysqli_query($connect,$sql);
$check = mysqli_fetch_array($result);
if(mysqli_num_rows($check) > 0)
{
if($check["password"] == $password){
echo 'Success';
}else{
echo 'pls enter correct password';
}
}
else
{
echo 'Invalid id';
}
}
?>
You can also refer this tutorial for more information
Split your SQL statement into to, at first query WHERE rollno = '$rollno', if found go on and query WHERE rollno = '$rollno' AND password = '$password', if everything's correct go on, if first statement fails user is not found, if second query fails, the user is found but password is not matching, this is your desired case.
When writing an authentication flow you can keep following things in mind :
validate your input data well
when interacting with Select queries use prepared statements whenever possible
use sha1 and md5 combinations on the password string to store in the database and comparisons.
I have tried to implement these things in the following code, of course there's always scope for improvement
function checkRollno($conn, $rollno)
{
$stmt = mysqli_stmt_init($conn);
$prepareQuery = "SELECT count(*) FROM tablename WHERE rollno = ?";
//Prepared Statements
if( mysqli_stmt_prepare($stmt, $prepareQuery ) )
{
// Bind params
mysqli_stmt_bind_param($stmt, 'i', $rollno);//i is for integer
/* execute query */
mysqli_stmt_execute($stmt);
/* Fetch Result */
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_assoc($result);
/* close statement */
mysqli_stmt_close($stmt);
if( count($row) < 1 )
return false;
else
return true;
}
else
return false;
}
function checkUserExists($conn, $rollno, $pass)
{
$stmt = mysqli_stmt_init($conn);
$prepareQuery = "SELECT count(*) FROM tablename WHERE rollno = ? AND password= ?";
//Compare sha1 of md5 of your password (You should not store or check against exact password strings)
$pass = sha1(md5($pass));
//Prepared Statements
if( mysqli_stmt_prepare($stmt, $prepareQuery ) )
{
// Bind params
mysqli_stmt_bind_param($stmt, 'is', $rollno, sha1(md5($pass)));// s is for strings
/* execute query */
mysqli_stmt_execute($stmt);
/* Fetch Result */
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_assoc($result);
/* close statement */
mysqli_stmt_close($stmt);
if( count($row) < 1 )
return false;
else
return true;
}
else
return false;
}
//Main Block
if( $_SERVER['REQUEST_METHOD'] == 'POST' )
{
if( isset($_POST['rollno']) && $_POST['rollno'] != '' )
$rollno = $_POST['rollno'];
if( isset($_POST['password']) && $_POST['password'] != '' )
$pass = $_POST['password'];
$res = checkRollno($conn, $rollno);
if( $res )//rollno exists
{
if( checkUserExists( $conn, $rollno, $pass ) )
die('authenticated');//Authenticated
else
die('denied');//Wrong password
}
else//rollno doesn't exist
{
//code to reflect wrong id does not exist
}
}
I am sure you can use better function names :)
Prepared Statements
Your code could look like this :
$sql = "SELECT * FROM registration_user WHERE rollno = '$rollno'";
$result = mysqli_query($connect,$sql);
$check = mysqli_fetch_array($result);
Then you can do checks :
if(mysqli_num_rows($check) > 0)
{
if($check['password']===$password){
//id and pass correct
}else{
// id correct , but bad password
}
}else
{
echo 'Invalid id';
}
Related
Hello I have been encountering this bug for a long time.
So basically here is by code:
function loginUser($conn, $username, $password) {
$checkExists = checkExists($conn, $username, $username);
if ($checkExists === false) {
header("Location: ../login.php?error=wronglogininfo");
exit();
}
$passwordHashed = $checkExists['password'];
$checkPassword = password_verify($password, $passwordHashed);
if ($checkPassword === false) {
header("Location: ../login.php?error=wronglogin");
exit();
} elseif ($checkPassword === true) {
$query = "SELECT * FROM users WHERE username='$username' AND password='$checkPassword'";
$query_run = mysqli_query($conn, $query);
$usertypes = mysqli_fetch_array($query_run);
if ($usertypes['usertype'] == "admin") {
header('Location: ../login.php?admin');
} elseif ($usertypes['usertype'] == "user") {
header('Location: ../login.php?user');
}
}
}
function checkExists($conn, $username, $email) {
$sql = "SELECT * FROM users WHERE username = ? OR email = ?;";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: ../register.php?error=stmtfailed");
exit();
}
mysqli_stmt_bind_param($stmt, "ss", $username, $email);
mysqli_stmt_execute($stmt);
$resultData = mysqli_stmt_get_result($stmt);
if ($row = mysqli_fetch_assoc($resultData)) {
return $row;
} else {
$result = false;
return $result;
}
mysqli_stmt_close($stmt);
}
And so the errors work fine.
The real problem is that whenever I login with correct credentials it sends me to a 404 page with a directory I never put. I want it to send be to the admin panel or user page. Can anyone help?
This select looks like a road to ruin: SELECT * FROM users WHERE
username='$username' AND password='$checkPassword' If $checkPassword
is the result of a password_verify(). (Also be careful about possible
SQL injection.)
I suspect this is your main issue. This would essentially translate your query to:
SELECT * FROM users WHERE username = 'tony' AND password = '1';
This will likely return an empty result set, but your very next if statement is expecting a user array populated with data.
if ($usertypes['usertype'] == "admin") {
header('Location: ../login.php?admin');
} elseif ($usertypes['usertype'] == "user") {
header('Location: ../login.php?user');
}
What happens now? You won't be redirected anywhere and the current script will continue processing. So what can you do?
If you already have the user row, via checkExists() (could this be
named better?), why do another call to the database to get the
usertype?
You already have access to your user array because you called checkExists above and verified it is not false. Just use the array directly.
I just cleaned up your code a bit and added in some comments. I did not alter your queries in any way and didn't verify they are correct.
function loginUser($conn, $username, $password) {
// Renamed this variable
// Validate it and use this variable for the remainder of the function.
$user = checkExists($conn, $username, $username);
if ($user === false) {
header("Location: ../login.php?error=wronglogininfo");
exit();
}
$passwordHashed = $user['password'];
// Renamed this variable.
$validPassword = password_verify($password, $passwordHashed);
if ($validPassword === false) {
header("Location: ../login.php?error=wronglogin");
exit();
}
// You now know you have a user and a valid password.
// No need to select them again
if ($user['usertype'] == "admin") {
header('Location: ../login.php?admin');
exit;
}
if ($user['usertype'] == "user") {
header('Location: ../login.php?user');
exit;
}
// What happens if `usertype` not matched? You still need to handle this case?
}
function checkExists($conn, $username, $email) {
$sql = "SELECT * FROM users WHERE username = ? OR email = ?;";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: ../register.php?error=stmtfailed");
exit();
}
mysqli_stmt_bind_param($stmt, "ss", $username, $email);
mysqli_stmt_execute($stmt);
$resultData = mysqli_stmt_get_result($stmt);
// Cleaned up this if statement
if ($row = mysqli_fetch_assoc($resultData)) {
return $row;
}
return false;
}
I am trying to create a login system that will load a different homepage based upon what database their information is stored in - Whether they're a customer or a business.
I have created my registration and it is okay when I am trying to check just one database and it will log them in successfully.
I am unsure where to put this bit of code for the second database though - I keep receiving errors whenever i place it somewhere, I have used a similar sort of code for the first database.
mysqli_stmt_bind_param($stmt2, "s", $ema);
mysqli_stmt_execute($stmt2);
$result2 = mysqli_stmt_get_result($stmt2);
This is the code in full.
} elseif (!empty($ema) AND !empty($pas)) {
$sql1 = "SELECT * FROM users1 WHERE email1=?;";
$sql2 = "SELECT * FROM users2 WHERE email2=?;";
$stmt1 = mysqli_stmt_init ($conn);
$stmt2 = mysqli_stmt_init ($conn1);
//Check if there was an error reading data from database
if (!mysqli_stmt_prepare($stmt1, $sql1) AND !mysqli_stmt_prepare($stmt2, $sql2)) {
header("Location: ../splash.php?error=sqlerror");
} else {
mysqli_stmt_bind_param($stmt1, "s", $ema);
mysqli_stmt_execute($stmt1);
$result1 = mysqli_stmt_get_result($stmt1);
if($row1 = mysqli_fetch_assoc($result1)) {
$pwdcheck1 = password_verify($pas, $row1['pwd1']);
if($pwdcheck1 == false) {
header("Location:../splash.php?error=wrongdetails");
exit();
//If a username and password in the business account correlate, then load the business index.
} elseif ($pwdcheck1 == true){
session_start();
$_SESSION['userlog1'] = $row1['idUsers1'];
header("Location: ../../b/index1.php?login=success");
exit();
}
} elseif ($row2 = mysqli_fetch_assoc($result2)) {
$pwdcheck2 = password_verify($pas, $row2['pwd2']);
if($pwdcheck2 == false) {
header("Location: ../splash.php?error=wrongdetails");
exit();
} elseif ($pwdcheck2 == true) {
session_start();
$_SESSION['userlog2'] = $row2['idUsers2'];
header("Location: ../../t/index2.php?login=success");
exit();
}
}
}
} else {
header("Location: ../splash.php?error=usernotfound");
}
Thanks!
The fact you should have a single users table aside, the problem is coming from the numerous conditions, every one of them being useless.
Basically if you need to get the results from two queries, then you should execute them right away, one by one. Without any intermediate conditions
$sql = "SELECT * FROM users1 WHERE email1=?;";
mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, "s", $ema);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_assoc($result)
if (!$row) {
$sql = "SELECT * FROM users2 WHERE email2=?;";
mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, "s", $ema);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_assoc($result);
}
Now you can check the password
if(($row && password_verify($pas, $row['pwd'])) {
// OK
} else {
// not OK
}
am currently working on a project and i have the script for insertion.my table is called survey and the fields are id,username,password,province. the username is set to unique key. the insertion process is working fine without any duplicate entry but when i try to insert a duplicate entry at always shows me this error
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'bluff' for key 'username'
I know what this error mean, my problem is that how can i can if username already exist or not i want an alert message to pop up..
here is my code
class.user.php
public function username($username){
$stmt = $this->db->prepare("SELECT count(*) FROM tish_images WHERE username = :username");
$stmt->execute(array($username));
$number_of_rows = $result->fetchColumn();
if($number_of_rows >= 1) {
echo 'username does exist'; // or return so you get the value
} else {
echo 'username does not exist'; //also return?
}
}
public function create($username,$password,$province)
{
try
{
$stmt = $this->db->prepare("INSERT INTO tish_images(username,password,province) VALUES(:username, :password, :province)");
$stmt->bindparam(":username",$username);
$stmt->bindparam(":password",$password);
$stmt->bindparam(":province",$province);
$stmt->execute();
return true;
}
catch(PDOException $e)
{
echo $e->getMessage();
return false;
}
}
index.php
<?php
include_once 'DB.php';
$username = isset($_GET['username']) ? $_GET['username'] : '';
$password = isset($_GET['password']) ? $_GET['password'] : '';
$province = isset($_GET['province']) ? $_GET['province'] : '';
if(isset($_FILES['files'])){
$id = $_GET['id'];
$username = $_POST['username'];
$password = $_POST['password'];
$province = $_POST['province'];
if($crud->upload($id,$FILE_NAME,$FILE_SIZE,$FILE_TYPE,$username,$password,$province))
{
echo "<script type='text/javascript'>alert('Successfully Updated!');</script>";
}
else
{
echo "<script type='text/javascript'>alert('Updating Failed!');</script>";
}
}
if(isset($_GET['id']))
{
$id = $_GET['id'];
extract($crud->getID($id));
}
You should run a SELECT before performing the query to see if the username exists.
// count how many rows with user name exists
$checkUserStmt = $this->db->prepare("
SELECT count(1)
FROM tish_images
WHERE username = :username
");
$checkUserStmt->execute(array(":username" => $username));
// fetch the count result
if ($checkUserStmt->fetchColumn() > 0) {
// username already exists
} else {
// username available
} //if
A few notes.
You still might get a duplicate entry error if you have two users trying to register the same username at close interval.
You should hash the password see Secure hash and salt for PHP passwords
To check if username or email already exists. I added email in there as this is also useful. You don't want two users with the same email address. Well I wouldn't see the need for it. :)
Complete code added and up to date.
$query_check_user_name = $this->db_connection->prepare('SELECT user_name, user_email FROM users WHERE user_name=:user_name OR user_email=:user_email');
$query_check_user_name->bindValue(':user_name', $user_name, PDO::PARAM_STR);
$query_check_user_name->bindValue(':user_email', $user_email, PDO::PARAM_STR);
$query_check_user_name->execute();
$result = $query_check_user_name->fetchAll();
if ($result > 0) {
echo "Someone with that username/email already exists.";
} else {
//Continue with proccessing the form
}
OR
$query_check_user_name = $this->db_connection->prepare('SELECT user_name, user_email FROM users WHERE user_name=:user_name OR user_email=:user_email');
$query_check_user_name->bindValue(':user_name', $user_name, PDO::PARAM_STR);
$query_check_user_name->bindValue(':user_email', $user_email, PDO::PARAM_STR);
$query_check_user_name->execute();
$result = $query_check_user_name->fetchAll();
if ($result > 0) {
return true;
} else {
return false;
}
I am trying to make login script safe to stop hacking of my website. I am trying to use mysql_real_escape_string in my script can anyone guide me if i am wrong in this.
Here is my code
<?php
session_start();
include("lib/conn.php");
?>
<?php
$email=$_POST['user'];
$password=$_POST['password'];
if ($email && $password){
$query = "SELECT * FROM register WHERE email = '$email' AND password= '$password' and status = '1'";
mysql_real_escape_string($email);
mysql_real_escape_string($password);
$result = mysql_query( $query ) or die ("didn't query");
$num = mysql_num_rows( $result );
if ($num == 1){
$_SESSION['ocer']=$email;
header("Location: admin.php");
}
else {
header("Location: index.php?l=1");
}
}
?>
1.- Don't use mysql* functions because are deprecated, use mysqli_* functions or PDO
2.- You should use prepared statements, this is an example using mysqli_* functions:
<?php
$email=$_POST['user'];
$password=$_POST['password'];
if ($email && $password){
$query = "SELECT email, password
FROM register
WHERE email = ?
AND password= ?
AND status = '1'";
$stmt = mysqli_prepare($link, $sql);
mysqli_stmt_bind_param($stmt, 'ss', $email, $password);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $column1, $column2);
while (mysqli_stmt_fetch($stmt)) {
echo "Column1: {$column1}, Column2: {$column2}";
}
?>
First of all. Use PDO with bind parameter. Then you don't have to worry about injections.
mysql_real_escape_string returns the escaped string and should be used before constructing your query. Use is as so:
$password = mysql_real_escape_string($password);
Also. Don not retrieve by password and email. retrieve password by email and validate that there the same.
Hope it helps
Here is the example:
session_start();
include("lib/conn.php");
//using isset to avoid warnings.
$email = isset($_POST['user']) ? $_POST['user'] : null;
$password = isset($_POST['password']) ? $_POST['password'] : null;
//check if values are not null
if ($email !== null && $password !== null){
//escape email
$email = mysql_real_escape_string($email);
//retrieve password by email and limit 1 result
$query = "SELECT password FROM register WHERE email = '{$email}' and status = '1' LIMIT 1";
//run query
$result = mysql_query( $query ) or die ("didn't query");
//validate if query run correctly
if (!$result) {
echo 'Could not run query: ' . mysql_error();
exit;
}
//fetch row
$row = mysql_fetch_row($result);
//validate result
if ($row['password'] == $password){
$_SESSION['ocer']=$email;
header("Location: admin.php");
} else {
header("Location: index.php?l=1");
}
}
I've made a user class which validates the data passed through the form and then subsequently updates the database table users. I want to add extra functionality such as checking if the username and email exists in the table, I've added a little script however it doesn't seem to be working.
I inserted a duplicated email address and I did not get the error message "email exists" instead I get the success message "1 row inserted":
Am I doing something wrong below? Is there perhaps a better way to approach this?
public function insert() {
if (isset($_POST['submit'])) {
$email = isset($_POST['email']) ? $this->mysqli->real_escape_string($_POST['email']) : '';
$result = $this->mysqli->prepare("SELECT * FROM users WHERE email='".$email."'");
if ($result->num_rows) {
echo "email exisits!";
}
else
{
$stmt = $this->mysqli->prepare("INSERT INTO users (username, password, name, email) VALUES (?, ?, ?, ?)");
$stmt->bind_param('ssss', $username, $password, $name, $email); // bind strings to the paramater
//escape the POST data for added protection
$username = isset($_POST['username']) ? $this->mysqli->real_escape_string($_POST['username']) : '';
$cryptedPassword = crypt($_POST['password']);
$password = $this->mysqli->real_escape_string($cryptedPassword);
$name = isset($_POST['name']) ? $this->mysqli->real_escape_string($_POST['name']) : '';
$email = isset($_POST['email']) ? $this->mysqli->real_escape_string($_POST['email']) : '';
/* execute prepared statement */
$stmt->execute();
printf("%d Row inserted.\n", $stmt->affected_rows);
/* close statement and connection */
$stmt->close();
}
You are using the worst API you ever can choose.
With safeMysql it would be
$exists = $this->db->getOne("SELECT 1 FROM users WHERE email=?s", $_POST['email']);
if ($exists) {
echo "email exisits!";
}
With PDO it is slightly longer but usable
$stmt = $this->db->prepare("SELECT 1 FROM users WHERE email=?");
$stmt->execute(array($_POST['email']));
$exists = $stmt->fetchColumn();
if ($exists)
{
echo "email exisits!";
}
But with raw mysqli you will need a screenful of code only to check if user exists.
So, the whole function using safeMysql would be
public function insert()
{
if (!isset($_POST['submit'])) {
return FALSE;
}
$sql = "SELECT 1 FROM users WHERE email=?s";
$exists = $this->db->getOne($sql, $_POST['email']);
if ($exists)
{
echo "email exisits!";
return FALSE;
}
$sql = "INSERT INTO users SET ?u";
$allowed = array('username', 'name', 'email');
$insert = $this->db->filterArray($_POST, $allowed);
$insert['password'] = crypt($_POST['password']);
$this->db->query($sql, $insert);
return $this->db->afectedRows();
}
you need to use this code after prepare statement
$stmt->execute();
$stmt->store_result();
put this
if ($result->num_rows > 0) {
echo "email exisits!";
}
instead of
if ($result->num_rows) {
echo "email exisits!";
}
First, you are using prepare (great!) but then you are just passing in the value of email, effectively defeating the benefit of prepared statements.
Second, you never execute the query, which is why you don't get anything in num_rows.
public function insert() {
$result = $this->mysqli->prepare("SELECT COUNT(*) FROM users WHERE email=?");
$result->bind_param("s", $_POST['email']);
$result->execute();
$result->bind_result($email_count);
if ($email_count) {
echo "email exisits!";
} else {
# your other logic
From what I can see you're not assigning a value to num_rows prior to testing it with if ($result->num_rows), so it will always be 0