PHP/MySQL log in system - - php

I'm pretty new to both PHP and MySQL and I'm struggling to get my login system to function properly. The registration works fine, but when I run the login it doesn't recognise there is anything within the table matching the entered data. Below is the code I believe to be the problem area.
Thanks in advance.
<?php
function load($page = 'login.php')
{
$url = 'http://'.$_SERVER['HTTP_HOST'].
dirname($_SERVER['PHP_SELF']);
$url = rtrim($url,'/\/');
$url.= '/'.$page;
header("location:$url");
exit();
}
function validate($dbc,$email ='',$pwd='')
{
$errors = array();
if (empty($email))
{ $errors[] = 'Enter your email address.'; }
else
{ $e = mysqli_real_escape_string($dbc,trim($email));}
if (empty($pwd))
{ $errors[] = 'Enter your password.';}
else
{ $p = mysqli_real_escape_string($dbc, trim($pwd)); }
if (empty($errors))
{
$q = "SELECT adultID, FirstName, Surname "
. "FROM adult_information "
. "WHERE Email = '$e' AND Password = SHA1('$p')";
$r = mysqli_query($dbc, $q);
if (mysqli_num_rows($r) == 1)
{ $row = mysqli_fetch_array($r, MYSQLI_ASSOC);
return array( true, $row);}
else
{$errors[]='Email address and password not found.';}
}
return array(false,$errors);
}

I believe that you'll get what you're looking for if you change
$q = "SELECT adultID, FirstName, Surname "
. "FROM adult_information "
. "WHERE Email = '$e' AND Password = SHA1('$p')";
to
$p = SHA1($p);
$q = "SELECT adultID, FirstName, Surname "
. "FROM adult_information "
. "WHERE Email = '$e' AND Password = '$p'";
Whenever a PHP-to-MySQL query isn't performing as expected, my first step is to get a look at the SQL I'm actually passing to the database. In this case, it would be by inserting a line like echo '<p>$q</p>'; immediately after assigning the value of $q.
Sometimes it immediately becomes obvious that I've got a malformed query just by looking at it. If it doesn't, I copy the SQL code that appears and run it as a query within the database manager, to see what errors it throws and/or examine the resulting data.

Related

Creating PHP analytics for each user profile

I'm trying to create analytic data for each of the User Profiles by telling them how many visitors visited from city & country visited their profile.
This is what I'm currently doing.
session_start();
$analyticsuser = $_SESSION["analyticsuser"];
if($analyticsuser!=$author) //$author is where the id of each profile is stored.
{
$ip = $_SERVER['REMOTE_ADDR'];
$query = #unserialize(file_get_contents('http://ip-api.com/php/'.$ip));
if($query && $query['status'] == 'success')
{
$userip = $query['query'];
$usercountry = $query ['country'];
$usercity = $query['city'];
$connection = mysqli_connect("HOSTNAME","USERNAME","PASSWORD","leo_site") or die("Error " . mysqli_error($connection));
$sqlanalytics = "INSERT INTO member_analytics VALUES(NULL,\"$userip\",\"$author\",\"$usercity\",\"$usercountry\",now());";
$resanalytics = mysqli_query($connection, $sqlanalytics) or die("Error " . mysqli_error($connection));
}
else { echo 'Unable to get location'; }
}
$_SESSION["analyticsuser"] = $author;
I'm trying to get how many visitors visited their profile from different city & countries.
The problem I'm facing now is, if I visit a profile again after visiting another profile, the data is still recorded. This should not happen as we have already recorded the visitor for that profile.
There are so many ways to solve this issue, one of them which I mostly used is an feature of mysql.
First create a composite key using author and userip.
After that at place of insert run replace query. As per nature of replace query if its find same author and userip combination field it replace that row by new data and if there is no combination found it will insert it.
$sqlanalytics = "REPLACE INTO member_analytics VALUES(NULL,\"$userip\",\"$author\",\"$usercity\",\"$usercountry\",now());";
I have solved my problem, You have to read session ID to check everytime if a profile is already visited by a visitor.
Below is the correct code.
session_start();
$new_sessionid = session_id();
$connection = mysqli_connect("HOSTNAME","USERNAME","PASSWORD","leo_site") or die("Error " . mysqli_error($connection));
$sqlcanalytics = "SELECT * FROM member_analytics WHERE sessid=\"$new_sessionid\" AND uid=\"$author\";";
$rescanalytics = mysqli_query($connection, $sqlcanalytics) or die("Error " . mysqli_error($connection));
$numcanalytics = mysqli_num_rows($rescanalytics);
if($numcanalytics==0)
{
$ip = $_SERVER['REMOTE_ADDR'];
$query = #unserialize(file_get_contents('http://ip-api.com/php/'.$ip));
if($query && $query['status'] == 'success')
{
$userip = $query['query'];
$userisp = $query['isp'];
$organization = $query['org'];
$usercountry = $query ['country'];
$userregion = $query['regionName'];
$usercity = $query['city'];
$sqlanalytics = "INSERT INTO member_analytics VALUES(NULL,\"$userip\",\"$author\",\"$new_sessionid\",\"$usercity\",\"$usercountry\",now());";
$resanalytics = mysqli_query($connection, $sqlanalytics) or die("Error " . mysqli_error($connection));
}
else { echo 'Unable to get location'; }
}
Thanks for the help!

Reset password confirmation does not work properly?

It works if i put it like that where user_id = 3 or when i remove the where statement(WHERE user_id=".$user['user_id'].") but then all my password in the db change.
I used get method to get the userid like that
user_id=3&reset_token=xxxxxxxxx
<?php
if( isset($_GET['user_id']) && isset($_GET['reset_token']) ) {
$userid = $_GET['user_id'];
$reset_token = $_GET['reset_token'];
// Make sure user email with matching hash exist
$req = $heidisql->prepare("SELECT * FROM users WHERE user_id='$userid' AND reset_token='$reset_token' ");
$req->execute($userid, $reset_token );
$user = $req->fetch(PDO::FETCH_ASSOC);
if ($user) {
if (!preg_match ('%\A(?=[-_a-zA-Z0-9]*?[A-Z])(?=[-_a-zA-Z0-9]*?[a-z])(?=[-_a-zA-Z0-9]*?[0-9])\S{8,30}\z%', $_POST['new_pass'])
|| $_POST['new_pass'] !== $_POST['confirm_newpass'] ) {
echo 'Your new password did not match the new confirm password or is invalid!';
exit();
}
}
} else {
$newpassword = escape_data($_POST['new_pass']);
$newpass_hash = password_hash($newpassword, PASSWORD_BCRYPT);
$sql= "UPDATE users SET "
. "password_hashcode='$newpass_hash', "
. "reset_allocated_time=NULL, "
. "reset_token=NULL "
. "WHERE user_id=".$user['user_id']." "; //<- error here
// Make sure user email with matching hash exist
$result_newpass = $heidisql->prepare($sql);
$result_newpass->execute();
echo "Your password has been reset!";
exit();
}
already try user_id = '$userid'/ $_GET['user_id']
So, how should i define the variable user_id?
Still does not work
$req = $heidisql->prepare("SELECT * FROM users WHERE user_id=':user_id' AND reset_token=':reset_token' ");
$req->execute([':user_id'=>$userid, ':reset_token'=>$reset_token]);
$sql= "UPDATE users SET password_hashcode=':password_hashcode', reset_allocated_time=NULL, reset_token=NULL WHERE user_id=:user_id";
$result_newpass = $heidisql->prepare($sql); $result_newpass->execute([':user_id'=>$userid,':password_hashcode'=>$newpass_hash, ':reset_token'=>NULL, ':reset_allocated_time'=>NULL]);
- I believe the problem may lies with the get method cause it seems that I cannot properly access the user_id/reset_token in the URL?
...localhost/example/reset_pass.php?user_id=xx&reset_token=xxxxxxxxx
I am getting undefined variable at user_id
Anyone knows if that the problem(s) cause my password validation also does not work?
Update this $sql from here:
$sql = "UPDATE users SET
password_hashcode = '$newpass_hash',
reset_allocated_time = NULL,
reset_token = NULL
WHERE user_id = '$user['user_id']'";
When using prepared statements you don't actually include the values in the statement. Instead you use placeholders, and bind the values later.
Change:
$req = $heidisql->prepare(
"SELECT * FROM users WHERE user_id='$userid'
AND reset_token='$reset_token' "
);
$req->execute($userid, $reset_token );
To:
$req = $heidisql->prepare(
"SELECT * FROM users WHERE user_id=:id
AND reset_token=:token "
);
$req->execute([':id'=>$userid, ':token'=>$reset_token]);
See the docs
Further down, you have:
$newpassword = escape_data($_POST['new_pass']);
$newpass_hash = password_hash($newpassword, PASSWORD_BCRYPT);
It's probably a bad idea to change the password (escape) before hashing it. Just hash it; the result will be safe to use. Changing it runs the risk of the user's true password not being recognized if your escape function changes in the future.
Further down you should change:
$sql= "UPDATE users SET password_hashcode='$newpass_hash',"
. "reset_allocated_time=NULL, reset_token=NULL "
. "WHERE user_id=".$user['user_id']." "; //<- error here
$result_newpass = $heidisql->prepare($sql);
$result_newpass->execute();
To:
$sql= "UPDATE users SET password_hashcode=:newpass,"
. "reset_allocated_time=NULL, reset_token=NULL "
. "WHERE user_id=:id"; //<- error here
$result_newpass = $heidisql->prepare($sql);
$result_newpass->execute([':newpass'=>$newpass_hash, ':id'=>$userid]);

PHP if statement within if statement

I'm building a php site where i want the user to create his company.
The script is checking if the user has any companies registered already and then it should display if he does or doesn't.
If he doesnt have a registered company, he should see a form where he can register.
If he choose to register a company the script will check for any company with the same name or insert the row.
My only problem is that when there's already a company with that name the echo doesnt display.
I have written inside the code where the problem is.
<?php
$con=mysqli_connect("mysql","USER","PASS","DB");
if (mysqli_connect_errno()) { echo "Failed to connect to MySQL: " . mysqli_connect_error(); }
$result_get_companies = mysqli_query($con,"SELECT * FROM companies WHERE userid='". $login_session ."' ORDER BY companyid ASC") or die(mysqli_error());
if (mysqli_num_rows($result_get_companies) >= 1) {
while($row_companies = mysqli_fetch_array( $result_get_companies )) {
$result_get_company_owner = mysqli_query($con,"SELECT username FROM users WHERE userid='". $login_session ."'") or die(mysqli_error());
$company_owner = mysqli_fetch_assoc($result_get_company_owner);
echo 'THIS WORKS';
}
} else {
if (isset($_POST['create_first_company']) && !empty($_POST['company_name'])) {
$company_name_unsafe = mysqli_real_escape_string($con, $_POST['company_name']);
$company_name = preg_replace("/[^a-zA-Z0-9\s]/","",$company_name_unsafe );
$check_companies = "SELECT companyid FROM companies WHERE company_name='". $company_name ."'";
$what_to_do_companies = mysqli_query($con,$check_companies);
if (mysqli_num_rows($what_to_do_companies) != 0) {
echo 'THIS DOESNT WORK
It does register that is should go here
because it does not insert new row.
and when the value is = 0 it does go
to else ELSE below and insert row.';
} else {
$result_create_company = mysqli_query($con,"INSERT INTO companies (companyname)
VALUES ('". $login_session ."')")
or die(mysqli_error());
echo 'THIS WORKS';
}
} else {
echo 'THIS WORKS!';
}
}
?>

Update successfully but couldn't update into DB

I couldn't find any error. I tried the query on phpmyadmin and it works well but when I do in php page, it couldn't update into DB. The following code below:
$registerID = ($_POST['registerID']);
$firstName = ucwords(htmlspecialchars($_POST['firstName']));
$lastName = ucwords(htmlspecialchars($_POST['lastName']));
$emailAddress = htmlspecialchars($_POST['emailAddress']);
$mainAddress = ucwords(htmlspecialchars($_POST['fullAddress']));
$updateCity = ucwords($_POST['userCity']);
$updateCountry = $_POST['userCountry'];
$postalCode = strtoupper(htmlspecialchars($_POST['userZip']));
$profilePic = $_POST['pic'];
$updateProf = " UPDATE register_user
SET firstName='$firstName',
lastName='$lastName',
emailAddress='$emailAddress',
mainAddress='$mainAddress',
registerCity='$updateCity',
registerCountry='$updateCountry',
postalCode='$postalCode'
WHERE registerID = '$registerID'";
if (mysqli_query($mysqli, $updateProf)) {
echo "Record updated successfully";
} else {
echo "Error updating record: " . mysqli_error($mysqli);
}
In the end, there are no errors after I updated on the webpage, it just show Record updated successfully. But it didn't update into DB. Any ideas?
UPDATED CODING
$checkProfile = "SELECT * FROM register_user where emailAddress = '$emailAddress'";
$editProfile = mysqli_query($mysqli,$checkProfile);
if ($editProfile) {
if (mysqli_num_rows($editProfile) > 0) {
header("Location: event?error=That name of email has already been taken");
} else {
$updateQuery = "UPDATE register_user
SET firstName = '$firstName',
lastName = '$lastName',
emailAddress = '$emailAddress',
mainAddress = '$mainAddress',
registerCity = '$updateCity',
registerCountry = '$updateCountry',
postalCode = '$postalCode'
WHERE registerID = '$registerID'";
$updateResult = mysqli_query($mysqli,$updateQuery);
header("Location: profileUser");
}
}
After I updated, it still doesn't work after I am using prepared statement. Any ideas?
Try executing the query first, saving it into a variable.
then, check if the query executed by doing:
if(!$query) echo "Query error : " . $mysqli->error;
This will give you more detailed error report.

Check record exists db - error show

How do I check if username or email exists and then put a error message in my error array. Right now i have:
$sql = "SELECT username, email FROM users WHERE username = '" . $username . "' OR email = '" . $email . "'";
$query = mysql_query($sql);
if (mysql_num_rows($query) > 0)
{
echo "That username or email already exists";
}
But I want to check if it is the username OR the email that is existing and then put:
error[] = "username is existing"; //if the username is existing
error[] = "email is existing"; //if the email is existing
How to do?
It would be easier if you just did a quick true/false check in the SQL and checked the flag that came back.
$sql = "SELECT "
. "(SELECT 1 FROM `users` WHERE `username` = '" . mysql_real_escape_string($username) . "'), "
. "(SELECT 1 FROM `users` WHERE `email` = '" . mysql_real_escape_string($email) . "')";
$query = mysql_query($sql);
if (mysql_num_rows($query) > 0) {
$foundFlags = mysql_fetch_assoc($query);
if ($foundFlags['username']) {
$error[] = "username is existing";
}
if ($foundFlags['email']) {
$error[] = "email is existing";
}
} else {
// General error as the query should always return
}
When it does not find an entry, it will return NULL in the flag, which evaluates to false, so the if condition is fine.
Note that you could generalise it for a field list like this:
$fieldMatch = array('username' => $username, 'email' => $email);
$sqlParts = array();
foreach ($fieldMatch as $cFieldName => $cFieldValue) {
$sqlParts[] = "(SELECT 1 FROM `users` WHERE `" . $cFieldName . "` = '" . mysql_real_escape_string($cFieldValue) . "')";
}
$sql = "SELECT " . implode(", ", $sqlParts);
$query = mysql_query($sql);
if (mysql_num_rows($query) > 0) {
$foundFlags = mysql_fetch_assoc($query);
foreach ($foundFlags as $cFieldName => $cFlag) {
if ($foundFlags[$cFieldName]) {
$error[] = $cFieldName . " is existing";
}
}
} else {
// General error as the query should always return
}
NB. Note that assumes all fields are strings, or other string-escaped types (eg. date/time).
Sounds like you're trying to let users know whether a username or email already exists at registration time. Here's what you can do:
<?php
//----------------------------------------
// Create first query
$usernameQuery = 'SELECT username FROM users WHERE username="'.mysql_real_escape_string($username).'"';
//----------------------------------------
// Query db
$usernameResult = mysql_query($userNameQuery);
//----------------------------------------
// Check if result is empty
if(mysql_num_rows($usernameResult) > 0){
//----------------------------------------
// Username already exists
$error[] = 'Username already exists';
//----------------------------------------
// Return error to user and stop execution
// of additional queries/code
} else {
//----------------------------------------
// Check if email exists
//----------------------------------------
// Create query
$emailQuery = 'SELECT email FROM users WHERE email="'.mysql_real_escape_string($email).'"';
//----------------------------------------
// Query the db
$emailResult = mysql_query($emailQuery);
//----------------------------------------
// Check if the result is empty
if(mysql_num_rows($emailResult) > 0){
//----------------------------------------
// Email already exists
$error[] = 'Email already exists';
//----------------------------------------
// Return error to user and stop execution
// of additional queries/code
} else {
//----------------------------------------
// Continue with registration...
}
}
?>
Please note that you should always escape your values before executing the actual query.
Additional Resources:
http://us.php.net/manual/en/function.mysql-real-escape-string.php
http://us.php.net/manual/en/function.mysql-escape-string.php
You can fetch one row and see if you got same email that you search or same username or both. You can do LIMIT 0,1 if you can stop after finding first row matching either this or that.

Categories