mysqli bind_result and fetch - php

I've created an arbitrary login system for users on the app I'm developing, and I am using mysqli to switch from MySQL. However, I'm having teething issues, as it will log you in successfully regardless of what data you enter. Obviously this is wrong, and I think it's got something to do with my fetch statements. Here is the code:
$sid = /* arbitrary value */
$con = new mysqli($mysql_host,$mysql_user,$mysql_password,$mysql_database);
$stmt = $con->prepare("SELECT uid, pwd FROM schools WHERE uid=?");
$stmt->bind_param("i", $sid);
$stmt->execute();
$stmt->bind_result($schoolid, $password);
$stmt->fetch();
$stmt->close();
Anybody know what's going on here and able to describe it in plain English to a relative coding newbie?
EDIT: the rest of the code is like this for the checking system. The entered user ID is $sid and the entered and encrypted password is $cleanpwd.
if ($sid == $schoolid and $cleanpwd == $password) {
header('Location: loginsuccess.php');
}
else {
header('Location: login.php?error=1'); }

It seems that if this is a login form are you getting the data first and then processing if it is correct? Or are you trying to process if it is correct (a userid and password combo in the SQL)? Because from this you are just putting in a userid and getting back a userid and password without checking if any entered password matches the database password associated with that userid.
If you want to see if the password and username match in the SQL you should try this:
$stmt = $con->prepare("SELECT uid, pwd FROM schools WHERE uid=? AND pass=?");
$stmt->bind_param("is", $sid,$form_password);
$stmt->execute();
otherwise you need to check if the data matches up later on.
if($_POST['form_pass'] == $password){
//log the user in
}

Related

Difficulty in Fetching data for logged in user

Here is my login process, I want a same dashboard but data will be different for each user. But I am stuck with creating uid variables to get data for each login user.
if(isset($_POST['login_btn']))
{
$email_login=$_POST['email'];
$password_login=$_POST['password'];
$admin="admin";
$co_admin="co_admin";
$query = "SELECT * FROM registered_users WHERE email='$email_login' AND password='$password_login' AND usertype='$admin' ";
$query_run = mysqli_query($connection, $query);
$query_co = "SELECT * FROM registered_users WHERE email='$email_login' AND password='$password_login' AND usertype='$co_admin' ";
$query_run_co = mysqli_query($connection, $query_co);
if(mysqli_fetch_array($query_run))
{
$_SESSION['username'] = $email_login;
$_SESSION['usertype'] = $admin;
header('Location: index.php');
}
else if(mysqli_fetch_array($query_run_co))
{
$_SESSION['username'] = $email_login;
$_SESSION['usertype'] = $co_admin;
header('Location: company_view.php');
}
else
{
$_SESSION['status'] = 'Email ID / Password / User Type is Invalid';
header('Location: login.php');
}
}
Above source code is for separating Co-admin and Admin. Now Any Co-Admin login to the portal he should get his own details, I would like to know which function I have to call or how should I declare a uid variable to fetch data tables for each current logged in user. I found some other source codes but which is not related to me so i am confused with how I fix it with those code. Can anyone do it in my codes.
I think you are asking how to get data for the current user from mysql tables. Yes, the standard way of doing this is via a unique ID for each user that is pulled from the registered_users table, storing this in the session, and then referencing this in the other tables and filtering by this ID. I would not suggest storing anything else from this table in the session as the ID is likely to have a stronger guarantee of imutibility.
For example if you have a table of recently visited pages per user, you would get this via:
$query = 'SELECT * from recently_visited WHERE user_id = ?';
$stmt = mysqli_prepare($query);
$stmt->bind_param("i", $_SESSION['user_id']);
$stmt->execute();
You can check the mysqli documentation for how to then extract what you need from the executed statement. I've shown this example of a prepared statement so you can see how to avoid SQL injection as well.
You may want to look into using foreign keys to enforce this connection.

PHP: Login system, querying a second table?

I have a very basic PHP login system which I'm altering right now for a product. The user is able to register with a username/password and the information is stored into a database. However, I have a separate table called "act_codes" which has a row called "act". I want to store activation codes in that table. For example, I would have "Code1" "Code2" and "Code3" in the act row. The user would login with their username and password, but they'd also need to enter their activation code which is generated via my ecommerce platform and emailed to them.
So far I have this for validating username/password which works fine:
if(empty($username_err) && empty($password_err) && empty($code_err)){
$sql = "SELECT username, password FROM users WHERE username = ?";
if($stmt = mysqli_prepare($link, $sql)){
mysqli_stmt_bind_param($stmt, "s", $param_username);
$param_username = $username;
if(mysqli_stmt_execute($stmt)){
mysqli_stmt_store_result($stmt);
if(mysqli_stmt_num_rows($stmt) == 1){
mysqli_stmt_bind_result($stmt, $username, $hashed_password);
if(mysqli_stmt_fetch($stmt)){
if(password_verify($password, $hashed_password)){
session_start();
$_SESSION['username'] = $username;
$_SESSION['code'] = $code;
header("location: welcome.php");
} else{
$password_err = 'The password you entered was not valid.';
}
}
} else{
$username_err = 'No account found with that username.';
}
}
}
mysqli_stmt_close($stmt);
}
I can't seem to figure out how to alter this code to also include the validation of the activation code from my second table. Could someone help me out by chance? Thank you very much!
Some points:
as a side point: put session_start() at the top of the script
And include a die statement immediately after your header("Location:...);
Are these two lines in the wrong order?
mysqli_stmt_bind_param($stmt, "s", $param_username);
$param_username = $username;
They should be set frst and then bound.
To answer your query
You seem to want a MySQL JOIN such as :
SELECT users.username, users.password act.var_code
FROM users
LEFT JOIN act ON users.userid = act.userid
WHERE username = ?
This is a rough result as I can't see your table structre, but feel free to read other Stack Overflow questions on a similar vain.
What type of MySQL join you use is entirely up to you. I have used LFET JOIN simply as an example.
As also referenced by d3t0x in their answer you will need to bind the additional data returned by MySQL, as well.
Why not use an inner join and this will mean you can keep using just the one query:
$sql1 ="SELECT users.username, users.password, codes.code FROM users INNER JOIN codes ON users.username = codes.username";
You will also need to bind the returned code to a variable so you can compare it with the code in the session.
Something like:
mysqli_stmt_bind_result($username, $hashed_password, $code);
This is presuming your table structure is:
users table = username, password
codes table = username, code

Why does it keep saying fatal error bind parameter on a non object

<?php
include('db_conx.php');
$username= $_POST ['username'];
$password= $_POST ['password'];
//Test:
echo "<h1>Username: $username</h1>";
echo "<h1>Password: $password</h1>";
$mysqli=new mysqli
('localhost','1800758_robbie','mypassword', '1800758_robbie');
$stmt=$mysqli->prepare("SELECT username, password FROM
1800758_robbie.users3 WHERE username=? AND password=? LIMIT 1");
**$stmt->bind_param('ss', $username,$password);**
$stm->execute();
$stmt-> store_result();
$res=$stmt->num_rows();
if($res == 1) {echo "You have successfully logged in.";}else{echo " the
username and password you've supplied is not valid.";}
?>
I have tried reading several other posts but none match this code. I am so lost as to why I keep getting this error message. All I want to do is create a succesful login page for a forum. BTW I have all my login information correct on my end.
Looks like an error in your prepare statement. Try this:
"SELECT username, password FROM users3 WHERE username=? AND password=? LIMIT 1"
You don't need to reference the database name for the users3 table, you already specified the table in your DB connection. If that still doesn't work make sure your table actually has fields named username and password.

Cannot login in PHP/MySQL

I've been modifying my code but I still can't log in... I have a MySQL database with a database called "users" with a table called "Users" and the following rows "UserNameID", "userName" and "password". I have created just an entry in order to test that:
+------------+----------+-----------+
| UserNameID | userName | password |
+------------+----------+-----------+
| 1 | root | pass |
+------------+----------+-----------+
Here my code:
<!DOCTYPE html>
<?php session_start(); ?>
<html>
<head>
<title>File1</title>
</head>
<body>
<?php
$DB_connection = mysqli_connect("localhost","user1","user1","users") or die("ERROR. Failed to connect to MySQL." . mysqli_error($DB_connection));
function SignIn() {
$usr = $_POST['user'];
$pw = $_POST['pwd'];
if(!empty($usr)) {
$query = mysql_query("SELECT * FROM Users where userName = '$usr' AND password = '$pw'");
$result = mysqli_query($DB_connection,$query);
if($result) {
while($row = mysqli_fetch_array($result)) {
echo "SUCCESSFULLY LOGIN TO USER PROFILE PAGE..."; }
} else {
echo "SORRY... YOU ENTERD WRONG ID AND PASSWORD... PLEASE RETRY..."; } }
}
SignIn();
mysqli_close($DB_connection);
?>
</body>
</html>
When I introduce a wrong password or username, it gives me "SORRY... YOU ENTERD WRONG ID AND PASSWORD... PLEASE RETRY...". However, it throws me the same when I put the correct password and username. What is wrong in my code?
Thanks a lot!
There numerous issues here. There are scoping issues, you are using the wrong methods, it's unsafe.
First off, these 2 lines:
$query = mysql_query("SELECT * FROM Users where userName = '$usr' AND password = '$pw'");
$result = mysqli_query($DB_connection,$query);
That's not how you query a database. You only need to call either mysql_query or mysqli_query depending on what API you are using. You are using MySQLi in this case, so do this:
$query = "SELECT * FROM Users where userName = '$usr' AND password = '$pw'";
$result = mysqli_query($DB_connection,$query);
Second, your SignIn function can't access the $DB_connection variable, it's out of scope. You need to pass it in:
function SignIn($DB_connection){
}
SignIn($DB_connection);
Third, this code is very unsafe! Never use $_POST directly in an SQL query like that. You should never be concatenating variables into an SQL string, you should use prepared statements.
// Don't use "SELECT *", use the fields you want
$query = mysqli_prepare($DB_connection, 'SELECT user_id FROM Users where userName = ? AND password = ?');
// This sends the values separately, so SQL injection is a thing of the past
mysqli_stmt_bind_param($query, 'ss', $usr, $pw);
// Run the query
mysqli_stmt_execute($query);
// Prepared statements require to define exactly the fields you want
mysqli_stmt_bind_result($query, $user_id);
// Get the data
while(mysqli_stmt_fetch($query)){
echo $user_id;
}
mysqli_stmt_close($query);
Lastly, storing plaintext passwords is bad practice. Use a hashing library. PHP 5.5+ has one built-in (http://php.net/password). There's also a version for lesser PHP versions (https://github.com/ircmaxell/password_compat).
P.S. As pointed out in the comments (here's a link), your session_start() is in the wrong spot. That sends a header, so it requires that there be nothing echoed out before it.
<?php session_start(); ?>
<!DOCTYPE html>
<html>
Make sure that there is no whitespace (or anything) before the session_start().
Your problem is here:
$query = mysql_query("SELECT * FROM Users where userName = '$usr' AND password = '$pw'");
This should instead be
$query = "SELECT * FROM Users where userName = '$usr' AND password = '$pw'";
You're then passing the query string rather than a resource to mysqli_query.
(Also, refer to Shankar Damodaran's answer regarding the scope issue: pass $DB_connection to the SignIn function).
As a side note, you shouldn't use posted data directly into the query. You're at risk of SQL injection. Look into sanitizing the data or, preferably, prepared statements.
First of all, you are running into scope issues here.
In this line...
$result = mysqli_query($DB_connection,$query);
The variable $DB_connection is not accessible inside your SignIn() and thus your query is getting failed. Also you are mixing mysql_* (deprecated) functions with mysqli_* functions.
This simple and small code snippet for the login might help you..
$con = mysqli_connect("localhost","user1","user1","users") or die("ERROR. Failed to connect to MySQL." . mysqli_error($con));
$username = $_POST['username'];
$password = $_POST['userpassword'];
$result = mysqli_query($con,"SELECT * FROM users WHERE user_name = '$username' and user_password='$password'");
$count=mysqli_num_rows($result); // get total number of rows fetched. needs only 1 row for successful login.
if($count==1){
//Login successful
}
else{
//Login unsuccessful
}
It will fetch a row if the entered username and password are matched.It will fetch only one row as the username and password will be unique. If the count of rows fetched is '1' you can have successful login.

Verified Emails Query

I have the following table
Login
IdUser (int)
Username(varchar)
Password(varchar)
Email(varchar)
Active(int)
Active is either 0 or 1 depending on if the users email is verified or not. If an account is verified the active row in the table is updated with a 1. If an account is not verified the active row in the table remains a 0.
Users should only be able to login if their account is verified.
So far my login works like this:
//login API
function login($user, $pass) {
// try to match a row in the "login" table for the given username and password
$result = query("SELECT IdUser, username FROM login WHERE username='%s' AND pass='%s' limit 1", $user, $pass);
if (count($result['result'])>0) {
// a row was found in the database for username/pass combination
// save a simple flag in the user session, so the server remembers that the user is authorized
$_SESSION['IdUser'] = $result['result'][0]['IdUser'];
// print out the JSON of the user data to the iPhone app; it looks like this:
// {IdUser:1, username: "Name"}
print json_encode($result);
} else {
// no matching username/password was found in the login table
errorJson('Authorization failed');
}
}
How would I give only users that are verified the ability to login?
Well, unless I'm missing something in your description, it seems that you simply have to add a AND active=1 to your WHERE clause. So you would end up with:
SELECT IdUser, username FROM login WHERE username='%s' AND pass='%s' AND active=1 limit 1
Updated
//login API
function login($user, $pass) {
// try to match a row in the "login" table for the given username and password
$result = query("SELECT IdUser, username, active, email FROM login WHERE username='%s' AND pass='%s' limit 1", $user, $pass);
if (count($result['result'])>0) {
// a row was found in the database for username/pass combination
if (!$result['result'][0]['active']) {
// not activated yet
errorJson('Not activated yet: ' + $result['result'][0]['email']);
} else {
// save a simple flag in the user session, so the server remembers that the user is authorized
$_SESSION['IdUser'] = $result['result'][0]['IdUser'];
// print out the JSON of the user data to the iPhone app; it looks like this:
// {IdUser:1, username: "Name"}
print json_encode($result);
}
} else {
// no matching username/password was found in the login table
errorJson('Authorization failed');
}
}
And by the way, as other mentionned, your code appears to be sensible to SQL injection, and you appear to store password in raw text in the database, which is a very bad practice. You should consider using mysqli + placeholders for your queries. You should also hash the passwords, at any point in the process. A simple way (though not the best) might be to use MySQL's password function. So your query would simply be changed to:
$result = query("SELECT IdUser, username, active, email FROM login WHERE username=? AND password=PASSWORD(?) limit 1", $user, $pass);
Simply add AND active = 1 before limit 1 in your query.
As an aside there are some broader issues with your code:
Avoid storing passwords directly in the database, use bcrypt instead, for example
Use mysqli or another database interface with prepared statements to avoid SQL injection
here:
$result = query("SELECT IdUser, username FROM login WHERE username='%s' AND pass='%s' AND emailVerified='1' limit 1", $user, $pass);
where there emailVerified is your email verified status field name, replace that to your own
first you have to check user is active or not
select active from login where username='%s';//execute this query and check result and store in active..
if(!$active)
{
errorJson("your account is not activated yet!);
}
else
{
//login code
}

Categories