0

I have a login page where I've set a query to check if the login & password entered match the database. The user should only be able to see the homepage if they are logged in.

The PHP Login validation on the login page works fine (if user/pass does not exist, it shows the error message. If the combination is correct, it redirects to the homepage just as it should):

LOGIN PAGE

<?php

    define('DB_LOCATION', 'x');
    define('DB_USERNAME', 'x');
    define('DB_PASS', 'x');
    define('DB_NAME', 'x');

    $dbc = mysqli_connect(DB_LOCATION, DB_USERNAME, DB_PASS, DB_NAME)
        or die('Error connecting to database');

    $error_message= "";

    $user_name = $_POST['user'];
    $user_password= $_POST['pass'];

    if (isset($_POST['submit'])) {

        // ADD QUERY TO CHECK IF USER/PASS COMBO IS CORRECT
        if(!empty($user_name) && !empty($user_password)) {

        $query = "SELECT * FROM employees WHERE username='$user_name' and password='$user_password'";

        $result = mysqli_query($dbc, $query)
            or die ('Error querying username/password request');

            if(mysqli_num_rows($result) == 1) {

                session_start();

                $_SESSION['user'] = $row['user'];
                $_SESSION['pass']= $row['pass'];


                header("Location: http://test.ishabagha.com/LESSON5/3%20-%20HOMEPAGE%20:%20WELCOME.php");

            } // end if rows

            else {
                $error_message = "You were not able to log in";
            } // end else

        } // end query

    } // end isset

?>

My issue is that on the homepage, I want to make it so that if the username and password have not been set/accepted, it redirects back to the login page and the homepage is not viewable. This is what I put in the PHP header - even if I haven't previously logged in, it still shows the page instead of directing it back to the login page (where he header/location is specified) and does not keep the home page private.

HOMEPAGE

<?php

    define('DB_LOCATION', 'x');
    define('DB_USERNAME', 'x');
    define('DB_PASS', 'x');
    define('DB_NAME', 'x');

    $dbc = mysqli_connect(DB_LOCATION, DB_USERNAME, DB_PASS, DB_NAME)
        or die('Error connecting to database');

    session_start();

    $user_name = $_SESSION['user'];
    $user_password= $_SESSION['pass'];

    if(!isset($_SESSION['user']) && !isset($_SESSION['pass'])) {

        header("Location: /LESSON5/1%20-%20LOGIN.php");
     }


?> 

Please let me know what it is is that could be causing the second part of the code on the homepage from redirecting.

Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141

3 Answers3

2

The problem is in your login page - $row does nothing, so your session arrays are never set.

You need to loop over $row

if(mysqli_num_rows($result) == 1) {

    while($row = mysqli_fetch_assoc($result)){
        $_SESSION['user'] = $row['user'];
        $_SESSION['pass']= $row['pass'];
    }
}
  • If mysqli_fetch_assoc fails, try mysqli_fetch_array().

Add error reporting to the top of your file(s) which will help find errors.

<?php 
error_reporting(E_ALL);
ini_set('display_errors', 1);

// rest of your code

Sidenote: Error reporting should only be done in staging, and never production.


Footnotes:

  • You should NOT store passwords in sessions arrays.
  • Your session could be hijacked.

Read up on sessions hijacking:


Edit:

Place

$user_name = $_POST['user'];
$user_password= $_POST['pass'];

inside your conditional statement

if(!empty($user_name) && !empty($user_password)) {...}

yet, replacing that with

if(!empty($_POST['user']) && !empty($_POST['pass'])) {
    $user_name = $_POST['user'];
    $user_password= $_POST['pass'];

// rest of code you wish to execute

}

and also setting blank assignments first:

$error_message= "";

$user_name = "";
$user_password= "";

if (isset($_POST['submit'])) {

$user_name = $_POST['user'];
$user_password= $_POST['pass'];

that is why you are getting undefined index notices.

Also this

<form name =loginForm method="post" action="<?php echo $_SERVER[' PHP_SELF' ];?>">

remove name =loginForm - Forms do not have name attributes.

Important factor:

  • Change $_SERVER[' PHP_SELF' ] to $_SERVER['PHP_SELF'] that is a syntax error and your form will fail and redirect.
  • There should not be any spaces in there.

Edit #2: (rewrite)

Here is a rewrite:

<?php 

error_reporting(E_ALL);
ini_set('display_errors', 1);

    session_start();

    define('DB_LOCATION', 'x');
    define('DB_USERNAME', 'x');
    define('DB_PASS', 'x');
    define('DB_NAME', 'x');

    $dbc = mysqli_connect(DB_LOCATION, DB_USERNAME, DB_PASS, DB_NAME)
        or die('Error connecting to database');

    $error_message= "";

    $user_name = "";
    $user_password= "";

    if (isset($_POST['submit'])) {

    $user_name = $_POST['user'];
    $user_password= $_POST['pass'];

        // ADD QUERY TO CHECK IF USER/PASS COMBO IS CORRECT
        if(!empty($user_name) && !empty($user_password)) {

        $query = "SELECT * FROM employees WHERE username='$user_name' and password='$user_password'";

        $result = mysqli_query($dbc, $query)
            or die ('Error querying username/password request');

            if(mysqli_num_rows($result) == 1) {

            while($row = mysqli_fetch_array($result)) {

                $_SESSION['user'] = $row['user'];
                $_SESSION['pass']= $row['pass'];

                }

                header("Location: /LESSON5/3%20-%20HOMEPAGE%20:%20WELCOME.php");
                exit;


        // echo "Welcome link here";


            } // end if rowns

            else {
                $error_message = "You were not able to log in";
            } // end else

        // Direct to other webpage

        } // end query



    } // end isset

?>

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Login</title>
  <link type="text/css" rel="stylesheet" href="/LESSON5/5_Signup_CSS.css">

</head>
<body>
<h1>Welcome to my website!</h1>
<h2>Please login below.</h2>
<h3>Don't have an account? <a href="/LESSON5/2%20-%20CREATE%20AN%20ACCOUNT.php">Create one here.</a></h3>

<div class="formFormat" >  
<div  id="table1">
<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
  <table id="cssTable">
    <tr>
        <td>Username:</td><td><input type="text" id="user" name="user" value="<?php echo $user_name; ?>" /></td>
    </tr>
    <tr>
        <td>Password:</td><td><input type="text" id="pass" name="pass" value="<?php echo $user_password; ?>"/></td>
    </tr>
      </table>

  </div>

  <div id="table2">

  <table> 
  <tr>
     <td><input type="submit" name="submit"/></td>
   </tr>
   <tr>
      <td id="createAccount"><a href="/LESSON5/2%20-%20CREATE%20AN%20ACCOUNT.php">Create an account</a></td>
   </tr>
   <tr>
    <td><?php echo $error_message ?></td>
   </tr>

  </table>
  </form>
  </div>
</div> 

<?php
//    mysqli_close($dbc);

if(isset($_SESSION['user']) && isset($_SESSION['pass'])) {

echo "Sessions are set";

}

else { 
  echo "Not set.";
}



?>

</body>
</html>

Passwords:

I noticed you may be storing passwords in plain text. If this is the case, it is highly discouraged.

I recommend you use CRYPT_BLOWFISH or PHP 5.5's password_hash() function. For PHP < 5.5 use the password_hash() compatibility pack.

Community
  • 1
  • 1
Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
  • Thanks, I changed it to this if(mysqli_num_rows($result) == 1) { while($row = mysqli_fetch_assoc($result)) { $_SESSION['user'] = $row['user']; $_SESSION['pass']= $row['pass']; } header("Location: /LESSON5/3%20-%20HOMEPAGE%20:%20WELCOME.php"); } // end if rows –  May 25 '15 at 10:32
  • @isha and the results are? – Funk Forty Niner May 25 '15 at 10:34
  • But now that I have that and the session_start() variables up top, when I enter the correct username/pass I'm directed back to the login page, this is sending me back to the login page (its on the homepage that I am supposed to be able to see after I login, instead I'm redirected back to the login as if I had not logged in) if(!isset($_SESSION['user']) && !isset($_SESSION['pass'])) { header("Location: /LESSON5/1%20-%20LOGIN.php"); } –  May 25 '15 at 10:35
  • @isha the problem may be in your HTML form then. Both elements bear the "name" attribute, correct? Error reporting in each page will signal any errors found. – Funk Forty Niner May 25 '15 at 10:37
  • @isha At this point, what you seem to be doing is assigning a new variable to your session arrays with `$user_name = $_SESSION['user']; $user_password= $_SESSION['pass'];` then add an `else{ echo "is set"; }` after your `if{...}` but I need to see what the HTML form looks like, please add to your question and NOT in comments. Try removing those assignments. – Funk Forty Niner May 25 '15 at 10:44
  • thanks. I tried the error reporting and got Notice: Notice: Undefined index: user in /home/ikb2014/public_html/test/LESSON5/1 - LOGIN.php on line 18 I think the issue lies in the post/variable. I will have to look into this. –  May 25 '15 at 10:46
  • 1
    @isha there you go, your `user` element in your form isn't set. It needs to read as `` same for the password `` with a POST method `method="post"` for the form. – Funk Forty Niner May 25 '15 at 10:47
  • @isha you also just overwrote your question with my answer without marking it as an edit underneath your original question. Please do not do that, otherwise people will see my answer and compare it with your question/code and tell themselves: *"it's all there, why the answer?"* - and I risk at getting downvoted for it. I performed a rollback to your original post. – Funk Forty Niner May 25 '15 at 10:50
  • Sorry about that and thanks for letting me know. I'll keep that in mind when making changes - still learning =) –  May 25 '15 at 10:52
  • @isha reload my answer and look under **Edit** near the bottom. That is why you are getting undefined index notices. – Funk Forty Niner May 25 '15 at 10:55
  • @isha I've made an additional edit under my **Edit**, reload it again. that is another reason why you're getting undefined index errors. You first need to set a blank assignment to both variables, then under the `if (isset($_POST['submit'])) {` conditional, adding `$user_name = $_POST['user']; $user_password= $_POST['pass'];` as shown in my answer. I tested your code with my answer, and it worked flawlessly. See also at the bottom where I say: Also `$_SERVER[' PHP_SELF' ]` to `$_SERVER['PHP_SELF']` that is a syntax error and is another reason why your form is failing. – Funk Forty Niner May 25 '15 at 11:17
  • Thanks for the HTML suggestions. I wish I had caught those errors before. Unfortunately, despite setting blank values and moving the arrays inside the statement, I'm still getting the index error, along with this error: "Warning: Cannot modify header information - headers already sent by.." I wonder why its working fine on your end, and not mine. I made the the exact changes. –  May 25 '15 at 11:31
  • @isha I've made a rewrite. Reload under **Edit #2: (rewrite)**. As for the Warning, you seem to have spaces before your ` – Funk Forty Niner May 25 '15 at 11:39
  • I tried out the code in Edit 2 with the debug outputs you added in. The only thing that's changed is that upon submit, the error messages are shown on a new page rather than on the same page as they were before. It's redirecting but only to a page showing errors. –  May 25 '15 at 11:52
  • @isha your other page contains errors and you need to correct those. For the headers warning, read the following on Stack http://stackoverflow.com/questions/8028957/how-to-fix-headers-already-sent-error-in-php and for the errors to show up on the same page, that I couldn't say. If you've some additional code you're not showing, like Javascript, then that could be it. I answered the initial question, and provided a solution. Anything beyond that, is "gravy". I believe I solved the initial/original question. You will need to take it from hereon in. – Funk Forty Niner May 25 '15 at 11:55
  • agreed and thank you. i appreciate you helping me get this far. –  May 25 '15 at 11:57
  • 1
    @isha *"the error messages are shown on a new page rather than on the same page"* - worked fine for me. When entering a wrong username or password, I get back `You were not able to log in` but you won't get the error message if only **one** field is filled. To get back an error if one **OR** the other wasn't entered, then you'd need to change the `&&` to `||` in your `if(!empty($user_name) && !empty($user_password)) {`. I believe the question should be marked as solved, far as I'm concerned, seeing the amount of time/work I put into this. – Funk Forty Niner May 25 '15 at 12:19
0

For your home page:

  • If your session does not contain user and password, two assignment statements may print out some errors.
  • You need an exit right after the redirect header to make sure that script will not print out any more output.

Consider this code:

<?php

    define('DB_LOCATION', 'x');
    define('DB_USERNAME', 'x');
    define('DB_PASS', 'x');
    define('DB_NAME', 'x');

    $dbc = mysqli_connect(DB_LOCATION, DB_USERNAME, DB_PASS, DB_NAME)
        or die('Error connecting to database');

    if(session_id() == '') {
        session_start();
    }

    if(!isset($_SESSION['user']) || !isset($_SESSION['pass'])) {
        header("Location: /LESSON5/1%20-%20LOGIN.php");
        exit(); // make sure that there is nothing printed after location header
    }

    $user_name = $_SESSION['user'];
    $user_password= $_SESSION['pass'];


?> 
Hieu Le
  • 8,288
  • 1
  • 34
  • 55
-2

Place session_start() at the top of both pages. By the way - no need to store password in the session,only user name and/or id.

Another problem, is that your code is vulnerable to sql injection. Use prepared statement to prevent this.

Ron Dadon
  • 2,666
  • 1
  • 13
  • 27