PHP login script issues - php

I have a couple of questions on my login script. It's just directing me to a blank page with no errors.
If I'm using mysqli, do I need to use ? or $username and $password in
my query?
I don't understand anything going on with $stmt -> fetch(); am I using it right?
$result=mysqli_query($stmt); : does this $result variable contain both the username and password?
If that's the case, how does mysqli_num_rows($result) work?
<?php
function clean($str)
{
$str = #trim($str);
if(get_magic_quotes_gpc()) {
$str = stripslashes($str);
}
return mysql_real_escape_string($str);
}
//Sanitize the POST values
$username = clean($_POST['username']);
$password = clean($_POST['password']);
/* Create a new mysqli object with database connection parameters */
$mysqli = mysqli_connect('localhost', 'root', '', 'draftdb');
if(mysqli_connect_errno())
{
echo "Connection Failed: " . mysqli_connect_errno();
exit();
}
/* Create a prepared statement */
if($stmt = $mysqli -> prepare("SELECT Login_ID, Login_PW,
FROM login
WHERE Login_ID='$username' AND Login_PW ='".md5($_POST['password'])."'"))
{
/* Bind parameters
s - string, b - boolean, i - int, etc */
$stmt -> bind_param("ss", $username, $password);
/* Execute it */
$stmt -> execute();
/* Bind results */
$stmt -> bind_result($username, $password);
/* Fetch the value */
while ($stmt->fetch())
{
$result=mysqli_query($stmt);
//Check whether the query was successful or not
if($result)
{//main if
if(mysqli_num_rows($result) == 1)
{
//Login Successful
session_regenerate_id();
$login = mysqli_fetch_assoc($result);
$_SESSION['SESS_MEMBER_ID'] = $login['Login_ID'];
//$_SESSION['SESS_FIRST_NAME'] = $login['firstname'];
//$_SESSION['SESS_LAST_NAME'] = $login['lastname'];
session_write_close();
header("location: member-index.php");
exit();
}
else {
//Login failed
header("location: login-failed.php");
exit();
}
}
else
{
die("Query failed");
}
}//main if close
/* Close statement */
$stmt -> close();
}
/* Close connection */
$mysqli -> close();
?>

I was attempting to address each of your questions but, they got so mixed that I couldn't just give you an answer for each. So i took the liberty of modifying your posted script with what i believe will make it work. Perhaps some extra tweaking is still necessary. Please review comments I added inline. Also, review the following php documentation pages for more information on using mysqli functions in its object oriented form:
http://www.php.net/manual/en/mysqli-stmt.num-rows.php
http://www.php.net/manual/en/mysqli-stmt.execute.php
http://www.php.net/manual/en/mysqli-stmt.bind-result.php
http://www.php.net/manual/en/mysqli-stmt.bind-param.php
I haven't tested it and i might have a typo or two, but here is my attempt at improving your script. Let me know what you think:
<?php
function clean($str)
{
$str = #trim($str);
if(get_magic_quotes_gpc()) {
$str = stripslashes($str);
}
return mysql_real_escape_string($str);
}
//Sanitize the POST values
$username = clean($_POST['username']);
$password = clean($_POST['password']);
/* Create a new mysqli object with database connection parameters */
$mysqli = mysqli_connect('localhost', 'root', '', 'draftdb');
if(mysqli_connect_errno())
{
echo "Connection Failed: " . mysqli_connect_errno();
exit();
}
/* Is your username the same as the login_id? If not you need to change this query's where to use the username column not the login_id. */
/* Create a prepared statement */
if($stmt = $mysqli -> prepare("
SELECT Login_ID, firstname, lastname
FROM login
WHERE Login_ID=? AND Login_PW=?
"))
{
/* Bind parameters
s - string, b - boolean, i - int, etc */
$stmt -> bind_param("ss", $username, md5($password));
/* Execute it */
$result = $stmt -> execute();
//Check whether the query was successful or not
if ($result === false) {
die("Query failed");
}
/* Bind results to variables that will be used within the fetch() loop. */
$stmt -> bind_result($login_id, $firstname, $lastname);
/* Check the number of rows returned. */
if ($stmt->num_rows !== 1) {
//Login failed
header("location: login-failed.php");
exit();
}
/* Iterate over the results of the query. */
while ($stmt->fetch())
{
//Login Successful
session_regenerate_id();
/* We can use $login_id, $firstname and $lastname cause we binded the result to those variables above. */
$_SESSION['SESS_MEMBER_ID'] = $login_id;
//$_SESSION['SESS_FIRST_NAME'] = $firstname;
//$_SESSION['SESS_LAST_NAME'] = $lastname;
session_write_close();
header("location: member-index.php");
exit();
}//main if close
/* Close statement */
$stmt -> close();
}
/* Close connection */
$mysqli -> close();
?>

When you're using a prepared statement, you normally shouldn't substitute variables into the statement. You put ? placeholders there, and then use $stmt->bind_param() to associate these placeholders with variables.
After using $stmt->fetch(), you can reference the variables that you bound with $stmt->bind_result to access the results of the SELECT.
You shouldn't be using mysqli_query at all if you're using a prepared statement. To answer your question about how it works, $result doesn't contain the actual data. You call something like $row = mysqli_fetch_assoc($result) to get the username and password into $row.
You should use $stmt->num_rows()

I am sorry friend i don't know much about mysqli.
But this can be easily done with mysql if you want.
By the way, for your 3rd question,
$result=mysqli_query($stmt); returns only the resource id's if there is any matching records for your search criteria. and mysqli_num_rows($result); will return how many resource id's are available for that criteria.username and password will only returned after mysqli_fetch_array($result); that will make the database to fetch the record as an array for those resource id's.
hope you understand...:))

I think, the problem is with this part of your code
while ($stmt->fetch())
{
$result=mysqli_query($stmt);
You have executed the statement, and fetched it; there is no need for you to query it again . . . . I'm not familiar with mysqli as I use PDO, but I think since you binded the result to $username, $password you can access the returned values with these binded variables.
while ($result = $stmt->fetch())
{
if($result->num_rows == 1)
{
$_SESSION['SESS_MEMBER_ID'] = $result['LOGIN_ID']
//////or $_SESSION['SESS_MEMBER_ID'] = $username
You can proceed like this, I think . . .

Related

password_verify having a few issues hopefully someone can help me

So im making a login for a game system that uses a JSON string to read back the files, however when I Hash the password and try login it doesn't work however when the password is unhased it works fine, I think the problem lies with the password verify part.
Im just unsure where to place it if someone could guide me in the right direction that will be amazing...
So the issue is when I send the $password example test5 it only reads as test 5 and not this $2y$10$viov5WbMukXsCAfIJUTUZetGrhKE9rXW.mAH5F7m1iYGfxyQzQwD.
This was the original Code
<?php
include("dbconnect.php");
/////// First Function To Get User Data For Login
if($_GET["stuff"]=="login"){
$mysqli = new mysqli($DB_host, $DB_user, $DB_pass, $DB_name);
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/////// Need to Grab Username And Password
$username = $_GET["user"];
$password = $_GET["password"];
$query = "SELECT username, password, regkey, banned FROM users WHERE username='$username' and password='$password'";
if ($stmt = $mysqli->prepare($query)) {
$stmt->execute();
$stmt->bind_result($username, $password, $regkey, $banned);
while ($stmt->fetch()) {
echo "{";
echo '"result": "success",';
echo '"regkey": "' . $regkey . '",';
echo '"banned": "' . $banned . '"';
echo "}";
}
$stmt->close();
}
$mysqli->close();
}
Then I tried This
<?php
include("dbconnect.php");
/////// First Function To Get User Data For Login
if($_GET["stuff"]=="login"){
$mysqli = new mysqli($DB_host, $DB_user, $DB_pass, $DB_name);
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/////// Need to Grab Username And Password
$username = $_GET["user"];
$password = $_GET["password"];
$GetPassword = "SELECT password FROM users WHERE username='$username'";
$data = mysqli_query($GetPassword);
if(password_verify($password, $data['password'])) {
$query = "SELECT username, password, regkey, banned FROM users WHERE username='$username' and password='$password'";
if ($stmt = $mysqli->prepare($query)) {
$stmt->execute();
$stmt->bind_result($username, $password, $regkey, $banned);
while ($stmt->fetch()) {
echo "{";
echo '"result": "success",';
echo '"regkey": "' . $regkey . '",';
echo '"banned": "' . $banned . '"';
echo "}";
}
$stmt->close();
}
} else {
// password is in-correct
}
$mysqli->close();
}
$data = mysqli_query($GetPassword);
^^^---mysqli result handle/object
if(password_verify($password, $data['password'])) {
^^^^^^^^^^^^---no such element in mysqli
You never fetched your data results, so you're comparing the entered password against a non-existent element of the $data result object/handle.
You need
$row = mysqli_fetch_assoc($data);
password_verify(..., $row['password']);
Most likely you're running with error_reporting and display_errors disabled, meaning you'd never see the "undefined index" warnings that PHP would ave been throwing everytime you ran this code. Those settings should NEVER be off on a devel/debug system.
And note that you're vulnerable to sql injection attacks, so your "security" system is anything but -it's entirely useless and trivially bypassable.
There are several issues with your code, such as:
This statement $data = mysqli_query($GetPassword) is wrong. mysqli_query() expects first argument to be your connection handler, so it should be,
$data = mysqli_query($mysqli, $GetPassword);
Look at this statement, if(password_verify($password, $data['password'])) { ...
mysqli_query(), on success, returns a result set, so you can't get the password using $data['password']. First fetch the row from the result set and then get the password, like this,
$row = mysqli_fetch_assoc($data);
if(password_verify($password, $row['password'])) { ...
Look at the following query,
$query = "SELECT username, password, regkey, banned FROM users WHERE username='$username' and password='$password'";
This query won't return any rows because of this WHERE condition, ...password='$password'. So the solution is, instead using two separate queries, use only one query to validate the password and retrieve relevant data. The solution is given down below.
Your queries are susceptible to SQL injection. Always prepare, bind and execute your queries to prevent any kind of SQL injection.
If you want to build a json string then instead of doing echo "{"; echo '"result": "success",'; ..., create an array comprising of all the relevant data and then json_encode the array.
So the solution would be like this:
// your code
$username = $_GET["user"];
$password = $_GET["password"];
// create a prepared statement
$stmt = mysqli_prepare($mysqli, "SELECT username, password, regkey, banned FROM users WHERE username=?");
// bind parameters
mysqli_stmt_bind_param($stmt, 's', $username);
// execute query
mysqli_stmt_execute($stmt);
// store result
mysqli_stmt_store_result($stmt);
// check whether the SELECT query returned any row or not
if(mysqli_stmt_num_rows($stmt)){
// bind result variables
mysqli_stmt_bind_result($stmt, $username, $hashed_password, $regkey, $banned);
// fetch value
mysqli_stmt_fetch($stmt);
if(password_verify($password, $hashed_password)){
echo json_encode(array('result' => 'success', 'regkey' => $regkey, 'banned' => $banned));
}else{
// incorrect password
}
}else{
// no results found
}
mysqli_stmt_close($stmt);
// your code

Checking if Username and Password are correct

As my code is right now, I always get the echo "Username/Password incorrect."; whether or not the username/password match or not. My question is, What did I do wrong in the code below for the php to always echo "Username/Password incorrect"
<?php
require 'privstuff/dbinfo.php';
$password1 = $_POST["password1"];
$username = $_POST["username"];
$mysqli = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_DATABASE);
if(mysqli_connect_errno()) {
echo "Connection Failed. Please send an email to owner#othertxt.com regarding this problem.";
exit();
}
if ($stmt = $mysqli->prepare("SELECT username, password FROM accounts WHERE username=? and password=?")) {
$db_pw = password_hash($password1, PASSWORD_BCRYPT);
$stmt->bind_param("ss", $username, $db_pw);
$stmt->execute();
if ($stmt->affected_rows > 0) {
echo "Logged in.";
}else{
echo "Username/Password incorrect.";
}
$stmt->close();
}
$stmt->close();
$mysqli->close();
?>
Update I've changed if ($stmt->affected_rows > 0) to if ($stmt->num_rows). Still doesn't work though
UPDATE 2 I've realized the issue is me using password_hash($password1, PASSWORD_BCRYPT); I didn't realize that the hash gives different strings every time. I'm not understanding on how to use password_verify
The documentation of mysqli_stmt_affected_rows() says:
This function only works with queries which update a table. In order to get the number of rows from a SELECT query, use mysqli_stmt_num_rows() instead.
You also need to call mysqli_stmt_store_results() first, to buffer the results.
$stmt->store_results();
if ($stmt->num_rows > 0) {
...
}
I figured it out. I was not supposed to use password_hash again. I didn't realize that using password_hash gave different results. I then changed it to use password_verify.
<?php
require 'privstuff/dbinfo.php';
$username = $_POST["username"];
$password1 = $_POST["password1"];
$mysqli = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_DATABASE);
// Check connection
if(mysqli_connect_errno()) {
echo "Connection Failed: " . mysqli_connect_errno();
exit();
}
/* create a prepared statement */
if ($stmt = $mysqli->prepare("SELECT `password` FROM `accounts` WHERE username = ?")) {
/* Bind parameters: s - string, b - blob, i - int, etc */
$stmt -> bind_param("s", $username);
/* Execute it */
$stmt -> execute();
/* Bind results */
$stmt -> bind_result($result);
/* Fetch the value */
$stmt -> fetch();
/* Close statement */
$stmt -> close();
}
if(password_verify($password1, $result))
{
echo("Hello");
}else{
echo("No-Go");
}
$mysqli->close();
?>

PHP/MySQL: Check if username exists

I'm a beginner in php and I want to check if the username entered already exists.
Here is my code.
<?php
ini_set('display_errors',1);
error_reporting(E_ALL);
if (isset($_POST['submit'])) {
include "connect.php";
ValidateUser();
}
function ValidateUser()
{
if (!empty($_POST['username']) AND !empty($_POST['password'])) {
$queryrow=mysqli_query("SELECT * FROM websiteusers WHERE username = '$_POST['username']'");
if ($rows=mysqli_num_rows($queryrow)=0) {
RegisterUser();
}
}
function RegisterUser() {
echo "works up to here";
}
?>
It doesn't even give me an error despite turning error reporting on.
Have you even initialized a mysqli_connect?
$Connection = mysqli_connect("host","user","pass","database");
Then pass it to a function which uses mysqli_query() by:
function foo ($DB){
mysqli_query($DB,"QUERY HERE");
// Do other stuff
return /* Whatever you wish to return here*/
}
foo($Connection);
What you are trying to achieve can be done very easily with the following code. A bigger concern is security. It is good practice to both sanitize your input every time the user has a chance to input text.
Also, using prepared query's will put yet another layer of security.
Although this isn't using your provided code directly, I believe it is good to teach good habits.
If you have any questions feel free to ask.
$username = $_POST['username']; <-- sanitize this
$message = null;
$mysqli = new mysqli("localhost", "user", "password", "database");
$stmt = $mysqli->prepare("SELECT username FROM websiteusers WHERE username=?");
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($usernamesql);
$stmt->fetch();
if ($stmt->num_rows() > 0) {
RegisterUser();
} else {
$message .= 'username already exists';
}
Later on when you require more items to be queried, or more results to be bound:
$stmt = $mysqli->prepare("SELECT username,password,other1,other2 FROM websiteusers WHERE username=?");
$stmt->bind_param('s', $username); <-- the "s" means the argument is a strings, if a argument is stored as an int use "i", but one character for each argument is required.
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($usernamesql);
$stmt->fetch();
Multiple Arguments:
$stmt = $mysqli->prepare("SELECT username,password,other1,other2 FROM websiteusers WHERE username=? AND authenticated=?");
$stmt->bind_param('si', $username,$isauthenticated); <-- second argument is a INT or BOOL
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($usernamesql,$passwordsql,$other1sql,$other2sql);
$stmt->fetch();
When your expecting multiple results, and lets say you want to dump them into arrays:
$userarray = array();
$stmt = $mysqli->prepare("SELECT username FROM websiteusers WHERE username=?");
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($usernamesql);
while($stmt->fetch()){
array_push($userarray, $usernamesql);
}
$userarray is now an array of all the results fetched from the database.
Here is the right way to do this:
<?php
ini_set('display_errors',1);
error_reporting(E_ALL);
if (isset($_POST['submit'])) {
$mysqli = new mysqli("localhost", "user", "password", "database");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
if(check_user($mysqli, $_POST['username']){
registerUser();
}else{
echo 'user exist, cannot register';
}
}
function check_user($conn, $username){
$query = "SELECT * FROM websiteusers WHERE username = ?";
if ($stmt = $conn->prepare($query)) {
$stmt->bind_param("s", $username);
$stmt->execute();
$stmt->close();
}
return $stmt->num_rows === 0;
}
function registerUser() {
echo "registering user ...";
}
Read up on prepared statement

Match user password in custom query php

I want to use my WordPress user table in my custom php app.Now the issue is if i try to check password against md5('password'); - it didn't work. How can i solve the issue.My query is
if($stmt = $mysqli -> prepare("
SELECT user_login, display_name
FROM wp_users
WHERE user_login=? AND user_pass=?
")){
/* Bind parameters
s - string, b - boolean, i - int, etc */
$stmt -> bind_param("ss", $username, md5($password));
How can i match the password to WordPress encrypted password?
Updates with Wp class.
function wp_hash_password($password) {
global $wp_hasher;
if ( empty($wp_hasher) ) {
require_once('class-phpass.php');
// By default, use the portable hash from phpass
$wp_hasher = new PasswordHash(8, true);
}
return $wp_hasher->HashPassword( trim( $password ) );
}
if(isset($_POST['login']))
{
$username = clean($_POST['login']['username']);
$password = wp_hash_password($_POST['login']['password']);
echo $password;
exit();
/* Create a new mysqli object with database connection parameters */
$mysqli = mysqli_connect('localhost', 'root', '', 'C347278_wordpress2');
if(mysqli_connect_errno())
{
echo "Connection Failed: " . mysqli_connect_errno();
exit();
}
if($stmt = $mysqli -> prepare("
SELECT user_login, display_name
FROM wp_users
WHERE user_login=? AND user_pass=?
")){
/* Bind parameters
s - string, b - boolean, i - int, etc */
$stmt -> bind_param("ss", $username, $password);
/* Execute it */
$result = $stmt -> execute();
//Check whether the query was successful or not
if ($result === false) {
die("Query failed");
}
/* Bind results to variables that will be used within the fetch() loop. */
$stmt -> bind_result($login_id, $display_name);
/* Check the number of rows returned. */
if ($stmt->num_rows != 1) {
//Login failed
$_SESSION['error_message'] = 'wrong User name OR Password';
}
/* Iterate over the results of the query. */
while ($stmt->fetch())
{
//Login Successful
session_regenerate_id();
/* We can use $login_id, $firstname and $lastname cause we binded the result to those variables above. */
$_SESSION['SESS_MEMBER_ID'] = $login_id;
$_SESSION['SESS_DISP_NAME'] = $display_name;
//$_SESSION['SESS_LAST_NAME'] = $lastname;
session_write_close();
header('Location:http://'.$_SERVER['SERVER_NAME'].'/app/'.$to);
exit();
}//main if close
/* Close statement */
$stmt -> close();
}
/* Close connection */
$mysqli -> close();
}
You can use wordpress native function,
$hash = wp_hash_password( $password );
Like,
$stmt -> bind_param("ss", $username, wp_hash_password($password));
Ref: http://codex.wordpress.org/Function_Reference/wp_hash_password
wp_hash_password() is located in wp-includes/pluggable.php.
Try CheckPassword() like this :
if($stmt = $mysqli -> prepare("
SELECT ID, user_login, user_pass, display_name
FROM wp_users
WHERE user_login=?
")){
$stmt -> bind_param("s", $username);
/* Execute it */
$result = $stmt -> execute();
//Check whether the query was successful or not
if ($result === false) {
die("Query failed");
}
/* Bind results to variables that will be used within the fetch() loop. */
$stmt -> bind_result($id,$login_id,$hash, $display_name);
/* Check the number of rows returned. */
if ($stmt->num_rows != 1) {
//Login failed
$_SESSION['error_message'] = 'Wrong User name OR Password';
}
/* Iterate over the results of the query. */
while ($stmt->fetch())
{
$wp_hasher = new PasswordHash(8, TRUE);
$check = $wp_hasher->CheckPassword($password, $hash);
if($check){ echo "Password matched" }

PHP login with Mysqli

I'm relatively new to php / mysqli i'm having trouble authenticating the user, I'm not exactly sure how to fetch a row and validate the data against it, then redirect user to a new page or display an error(all i know is i need to use _SESSION) . Basically i'm having trouble with the fetch() routine, what is the right way to code this?
<?php
session_start();
$username = trim($_POST['username']);
$password = trim($_POST['password']);
/* Create a new mysqli object with database connection parameters */
$mysqli = mysqli_connect('localhost', 'root', '', 'draftdb');
if(mysqli_connect_errno())
{
echo "Connection Failed: " . mysqli_connect_errno();
exit();
}
/* Create a prepared statement */
if($stmt = $mysqli -> prepare("SELECT Login_ID, Login_PW,
FROM login
WHERE Login_ID=? AND Login_PW =?"))
{
/* Bind parameters
s - string, b - boolean, i - int, etc */
$stmt -> bind_param("ss", $username, $password);
/* Execute it */
$stmt -> execute();
/* Bind results */
$stmt -> bind_result($username, $password);
/* Fetch the value */
if($stmt->fetch() == true)
{
$row =$query -> fetch();
$_SESSION['name'] = $row;
header("Location:/in.php");
exit();
}
else
{
echo 'Invalid Login';
}
/* Close statement */
$stmt -> close();
}
/* Close connection */
$mysqli -> close();
?>
Follow this order
Prepare Query $stmt->prepare()
Bind Param if you use placeholders $stmt->bind_param("ss", $username, $password);
Execute
Bind Results to variables $stmt->bind_result($username, $password)
The data is now ready to be picked up with $stmt->fetch()
Close prepared statement $stmt->close
I think it isn't clear to you that $stmt->bind_result() already sets up variables. In your case you are likely to only fetch 1 row from the table, so $stmt->fetch() is enough. If you have multiple rows you need a loop which you use to use the data.
example:
$a = array();
while ($stmt->fetch()) {
$a = array('username' => $username, 'password' => $password);
}
regarding the user and password match:
you now have
$_POST['username'];
$_POST['password'];
$username;
$password;
so you have have to make an if statement that checks $_POST['username'] == $username && $_POST['password'] == $password. If this is true, you can set your loggedin flag.
To keep a user logged in just set a $_SESSION variable. You could set $_SESSION['logged_in'] = true;, this gives you the possibility to know the user is already authenticated if this variable is set. If user wants to end his session, just unset the variable (and destroy session).
also one more thing I noticed:
if($stmt->fetch() == true) { } // equals: if ($stmt->fetch()) { }
This has major security issues, but to answer your question:
You can do something like this:
$sql = "SELECT Login_ID, Login_PW,
FROM login
WHERE Login_ID=?
";
$stmt = $mysqli->prepare( $sql );
// Do your thing...
// Make sure the user is found.
if ( ! $stmt->rowCount() )
return false;
// Retrieve your results as an associative array.
$user = $stmt->fetch();
// Check the password.
if ( ! $_POST['password'] == $user['Login_PW'] ) )
return false;
$_SESSION['name'] = $user['Login_ID'];
header("Location:/in.php");
exit();
You might find these useful:
Why you Should be using PHP’s PDO for Database Access
Secure Passwords with Phpass

Categories