Solved

Why does this login script not work on a live server?

Posted on 2016-11-09
19
40 Views
Last Modified: 2016-11-10
So, this works perfectly on my localhost but on a live server it does not. I do not get any errors or anything. It just does absolutely nothing and I can't figure out why.

@Ray, if you look at this I haven't yet fixed my mistake of $email = $_POST['email'], but I promise I will as soon as I can get this to work on a live server! :)

Anyway, here is the code I have.

<?php

function user_login($link) {
	
	if(isset($_POST['login'])) {
		
		$message = "";
		$email = $_POST['email'];
		$safe_email = filter_var($email, FILTER_SANITIZE_EMAIL);
		$stmt = $link->prepare("SELECT `admin_pass`, `safeID`, `admin_email` FROM `bb_admin` WHERE `admin_email` = ? LIMIT 1");
		$stmt->bind_param("s", $safe_email);
		$stmt->execute();
		$result = $stmt->get_result();
		$numRows = $result->num_rows;
		if($result) {
			$row = $result->fetch_assoc();
			$db_pass = $row['admin_pass'];
			if(password_verify($_POST['password'], $db_pass)) {
			$_SESSION['safeID'] = $row['safeID'];
			$fingerprint = md5($_SERVER['HTTP_USER_AGENT'] . $_SERVER['HTTP_ACCEPT_LANGUAGE']);
			$_SESSION['fingerprint'] = $fingerprint;
				header("location:dashboard.php");
				exit;
			
		} else {
				
				$message = "<div class='alert alert-danger'>Invalid user credentials</div>";
		}
			
			return $message;
		}
	}
}

// VALIDATE LOGGED IN USER

function isLoggedIn(){
	
	$fingerprint = md5($_SERVER['HTTP_USER_AGENT'] . $_SERVER['HTTP_ACCEPT_LANGUAGE']);
	
	if(!isset($_SESSION['safeID']) || (isset($_SESSION['fingerprint']) && ($_SESSION['fingerprint']) !== $fingerprint)){
		
		header("location:logout.php");
	}

	
}

Open in new window

0
Comment
Question by:Black Sulfur
  • 10
  • 6
  • 3
19 Comments
 
LVL 51

Accepted Solution

by:
Julian Hansen earned 350 total points
ID: 41881257
Comment out your header() statements
Temporarily change $_POST to $_GET
Put some echo's on lines 4,6,16,27 to test if execution got there.

Call script with ?email=TESTEMAIL&password=PASSWORD_FOR_THAT_EMAIL

That will allow you to test without your login form and see where execution is going / not going.

When working reverse out the changes.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 41881332
It looks like you have two function definitions, but no PHP code to call the functions.  Maybe the PHP scripts are slightly different on the local machine and the internet-deployed machine?
0
 

Author Comment

by:Black Sulfur
ID: 41881797
@ Ray,

No, the code is exactly the same. The login page has this at the top of it to call the function:

<?php
error_reporting(E_ALL);
session_start();
ob_start();
include ("../functions/db.php");
require 'functions/authentication.php';
?>

Open in new window


Then, under my actual login button I have:

<?php echo user_login($link); ?>

Open in new window

0
 

Author Comment

by:Black Sulfur
ID: 41881799
Then on the dashboard page I have:

<?php
session_start();
ob_start();
session_regenerate_id();
include ("../functions/db.php");
require 'functions/authentication.php';
isLoggedIn();
?>

Open in new window

0
 

Author Comment

by:Black Sulfur
ID: 41881806
@ Julian,

That sounds complicated but I will try it out as best I can.
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41881822
Standard AJAX testing procedure + debugging pages that have redirects.

It is not that complicated - all you are doing is changing your POST to GET so you can call the script with parameters using a URL rather than having to use a form to POST them.

You are putting // in front of the lines with the header() call on them to stop your page redirecting so you can see output and errors that may be causing the problem.

You are adding echo statements to track the progress through the code - so you can see how far it gets.
0
 

Author Comment

by:Black Sulfur
ID: 41881862
Everything works up until here:

if(password_verify($_POST['password'], $db_pass)) {

Open in new window


My suspicion is that this server doesn't support PHP7 and that's why the script stops working from a PHP 7 function which is password_verify()

They did however tell me that the server was running PHP7. Is there a script I can upload to verify? I seem to remember seeing one once before which gives you all the php details of the server but can't remember what it's called.
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41881906
password_verify() valid from PHP >= 5.5
But, yes if your PHP < 5.5 then it won't work.
There is this GitHub project that provides PHP functions for versions < 5.5
https://github.com/Antnee/phpPasswordHashingLib
0
 

Author Comment

by:Black Sulfur
ID: 41881909
Okay, confirmed that their server is not running php 7. I made an adjustment to the .htaccess file because they said I can get php 7 to work by doing that as they do support it. I did it and the script works fine :)
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 108

Assisted Solution

by:Ray Paseur
Ray Paseur earned 150 total points
ID: 41881949
My suspicion is that this server doesn't support PHP7...
Install this script, shown here in its entirety, and run it.  Look carefully at the output.  Give yourself about an hour of quiet time to study it.  Check the references on php.net for anything you do not immediately recognize.  Make a Google search for "PHP" plus anything else you don't fully understand.  In about an hour you will be way ahead in your understanding of PHP, I promise.
<?php phpinfo();

Open in new window

0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 41881971
Now let's turn to the question of general program structure.  Please take a moment to compare these script fragments:
<?php
error_reporting(E_ALL);
session_start();
ob_start();
include ("../functions/db.php");
require 'functions/authentication.php';

Open in new window

<?php
session_start();
ob_start();
session_regenerate_id();
include ("../functions/db.php");
require 'functions/authentication.php';
isLoggedIn();

Open in new window

Did you notice that I took out the close-PHP tags?  You should, too.  This is an antipractice that will cause you trouble one day, so get in the habit of not using the close-PHP tag.

Take a look at the similarity of these two script fragments.  They have a lot in common.  So much so, that it would make a lot of sense to combine them into common.php and use require_once('common.php'); as the first statement of all your application-specific scripts.  The most important characteristic of common.php is no side effects.  The common.php script must not create any browser output.  Once those design requirements are satisfied, you can begin to do useful work in common.php.  You can start the session and load any stateful (active record) data.  You can start the buffers.  You can connect to the database. You can load your classes, methods and functions.  And you can get all of this done with a single statement.  It's the kind of design that is described here.  Until your PHP work advances to the point that you need a framework, this simple require_once() design will meet all of your needs.  And because it will help you avoid redundancy, it will reduce your debugging and remediation load.
0
 

Author Comment

by:Black Sulfur
ID: 41881994
Hi Ray, quickly replying on my mobile to your first comment. The reason I have closing php tags is because there is HTML below that code, I don't normally close my php tags unless there is HTML that goes underneath it.
0
 

Author Comment

by:Black Sulfur
ID: 41881997
Obviously you would not know that though because I did not post the HTML...
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 41882028
php ... HTML ... underneath
Maybe consider using HEREDOC instead of putting PHP and HTML into the same file.  If you put your HEREDOC templates into a separate file that can be loaded with require_once() you can get very neatly organized PHP scripts.  Just a thought...
1
 

Author Comment

by:Black Sulfur
ID: 41882220
@ Ray,

I am glad you brought up the common.php topic because I have been meaning to ask about something similar.

I had the idea of not putting ALL my functions into one functions.php file for example. But I rather wanted to have something like,

authentication.hp
categories.php
vendors.php
customers.php

and so on. It would just be easier for me to identify which one I need to edit instead of searching through one functions file.

But I wanted to know if this would create extra strain on the server or use more resources to have something like a initialize.php file that includes or requires all those mentioned above.

But what you said about the common file totally makes sense, especially for something like sessions and ob_start()
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 41882341
There are arguments to be made on both sides of the common.php idea.  Here are some of my thoughts, in no particular order.

If you want to go very far with PHP (by that I mean, get a PHP job) you want to learn about Composer.

If you want to see native poor performance, install WordPress, add a few plug-ins or similar add-ons and then use YSlow or the Chrome console to watch the site as it loads file after file after file after file...

This is an oversimplification, but it's a useful way to look at disk I/O.  The I/O service time is the time it takes to read any disk file.  It is a combination of four things: Average Seek Time, average Rotational Delay (1/2 of a rotation), average Data Transfer, and average Queue time.  These things are measured in milliseconds.  We don't have much control over queue time.  Queue time varies geometrically with the inverse of the load on the I/O subsystem.  If the load goes above 25%, performance begins to suffer and response time becomes erratic.  We do have some control over the other parts.  Typically, data transfer accounts for only 1/4 to 1/3 of I/O service time.  This means that 65-75 percent of I/O service time is overhead.  The only way to reduce the overhead is to do fewer I/O operations.  You can reduce the number of I/O operations by reducing the number of script files your site must load.  Remember, this is measured in milliseconds, whereas in-memory instruction processing is measured in nanoseconds.  The time differences are several orders of magnitude, and it follows that optimization in the I/O subsystem is several orders of magnitude more valuable than optimization of program code.

If you have ten scripts in ten script files, your site will load more slowly than if you have ten scripts in one script file.  As a result, we have task runners (build systems) like Grunt that can be used to combine script files, and thereby get back some of the performance lost to separate script files.

When we find ourselves writing code for the same process for the third time, it's usually a good time to stop copying the code and start refactoring the code into a generalized solution set.  If you have to refactor similar code elements in several different PHP script files, you will find (as we all do) that this process inevitably leads to errors and omissions.

Never go to sea with two chronometers.  Likewise, apply the DRY principle whenever you can. If you only have to look in one place to find your classes, methods, initialization code, you have saved yourself considerable time through good organization.  If you have a moment, read this tutorial:
https://code.tutsplus.com/tutorials/3-key-software-principles-you-must-understand--net-25161

One of the great benefits of object-oriented design is the ability to reuse code.  An object that represents a client can represent a client in any number of related scripts, and you don't have to copy the client object definition over and over - you can just load it from a central library.  The central library can be a directory of code fragments, or it can be a single large PHP script, with all the code fragments brought together into one.  Small, distinct code fragments facilitate unit testing, but create poor performance in a deployed application.
1
 

Author Comment

by:Black Sulfur
ID: 41882524
Okay, wow. That's a lot of tech info.

if you have ten scripts in ten script files, your site will load more slowly than if you have ten scripts in one script file.

So, it sounds like I should rather put all my functions into one functions.php file instead of what I suggested earlier.

I was just thinking that putting

authentication.hp
categories.php
vendors.php
customers.php

into initialize.php and only calling initialize.php was kind of like just calling one file.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 41882600
This sort of thing generates a lot of file system overhead
<?php // initialize.php
error_reporting(E_ALL);
require_once('auth.php');
require_once('categories.php');
require_once('vendors.php');

Open in new window

Each one of those require() statements needs a disk lookup, file open, etc.  There is a lot of time involved, relatively speaking.

For performance purposes, a single require_once() that brings in a single script file (containing all of these scripts, merged together into one longer script) will be better.  That's the sort of issue that the build systems address.  They let you keep your scripts in separate files for development and testing, and then merge the scripts when you get ready for deployment.

BTW, this product is worth the money and time it takes to master the tool set.  
https://www.jetbrains.com/phpstorm/
1
 

Author Comment

by:Black Sulfur
ID: 41882608
okay, perfect. I will do that going forward.

yeah, I did see php Storm and it looks awesome! Maybe one day if I am making money from this I will get it but for now it's good ol' Adobe Brackets.
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Generating table dynamically is the most common issue faced by php developers.... So it seems there is a need of an article that explains the basic concept of generating tables dynamically. It just requires a basic knowledge of html and little maths…
I imagine that there are some, like me, who require a way of getting currency exchange rates for implementation in web project from time to time, so I thought I would share a solution that I have developed for this purpose. It turns out that Yaho…
The viewer will learn how to count occurrences of each item in an array.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now