0

I need to make quiz.php exclusive to logged-in users. This code did work the first three times I logged in. But when I refreshed quiz.php, it logged me out and wouldn't let me log back in, despite the fact that I was using the exact same credentials that had logged me in before (i.e. credentials defined in my SQL database called "indocTest").

The login page is set to echo "valid/invalid username" and "valid/invalid password" when processing the credentials, so it should be echoing text onto the page either way. Instead, it only echoes error messages when I enter invalid credentials. When I enter valid credentials, the page reloads itself and does nothing. It won't let me access the quiz.php page at all.

I've tried every variant of turning it off and turning it back on again -- from clearing my browser cache to closing the browser to restarting my laptop -- but the code is not working. How do I fix this?

This is what the user credentials database looks like:

Screenshot of table "users" in database "indocTest"

Below is my code:

<?php
include 'config.php'; /* Includes the PHP file that will create a database grades and table quizzes if none exists */
session_start();
if($_POST) {
  makeDB();
}

function makeDB() {
  # Creates the database
  $sql = "CREATE DATABASE IF NOT EXISTS indocTest";
  mysqli_query($GLOBALS['conn'], $sql);
  # selects a table in the database
  mysqli_select_db($GLOBALS['conn'], 'indocTest');

  # SQL to create table if it doesn't exist already
  $sql = "CREATE TABLE IF NOT EXISTS users(
    id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, # allows you to look up IDs for database queries, PRIMARY KEY must be unique
    firstname VARCHAR(30) NOT NULL, # allows the first name to be up to 30 characters
    lastname VARCHAR(30) NOT NULL,
    username VARCHAR(20) NOT NULL,
    password VARCHAR(20) NOT NULL,
    UNIQUE KEY(firstname, lastname)
  )";
  mysqli_query($GLOBALS['conn'], $sql);
  //$sql = "INSERT INTO users (firstname, lastname, username, password) VALUES ('Jane', 'Doe', 'Admin', 'navalacad05')";
  //mysqli_query($GLOBALS['conn'], $sql);
  checkUser();
}

function checkUser() {
  mysqli_select_db($GLOBALS['conn'], 'indocTest');
  # saves the form responses in local variables
  $username = $_POST['user'];
  $password = $_POST['password'];

  # checks the form data against the database
  $sql = "SELECT username, password FROM users where username='$username'";
  $result = mysqli_query($GLOBALS['conn'], $sql);
  $data = mysqli_fetch_assoc($result);
  echo $data['username'] . $data['password'];
  echo mysqli_num_rows($result);

  # if this returns a result, then the username is valid
  if (mysqli_num_rows($result)>0) { // mysqli_num_rows() expects parameter 1 to be mysqli_result, bool given === query issues
    echo "Good username";
  } else {
    echo "Wrong username";
  }

  $sql = "SELECT password FROM users where username='$username'";
  $pswd = mysqli_query($GLOBALS['conn'], $sql); # retrieves the corresponding password
  if ($data['password'] == $password) {
    $_SESSION['login_user'] = $username;
    header("location: quiz.php");
  } else {
    echo "Invalid password";
  }
}

mysqli_close($GLOBALS['conn']); # closes the connection
?>



<!DOCTYPE html>
<html>
<head><title>Login</title>
  <link href="style.css" type=text/css rel="stylesheet">
</head>

<body>
<center>
<!-- Prints instructions -->
<p>Login below!</p></center>

<!-- Links the form to a PHP script to grade the quiz -->
<form method="post">
<fieldset><center><br>
Username <input type='text' name='user' required><br><br>
Password <input type='text' name='password' required><br><br>
<!-- add a form page that changes dynamically so they can input their rank depending on whether they're enlisted or commissioned -->
<br>
<input type='submit' value='Login!'> <!-- Submit button -->
<!-- Ends the fieldset and form --></center>
</fieldset></form>

<center><p>Don't have an account? Make one <a href='register.html'>here</a>.</p></center>

</body>
</html>

And the header of my quiz.php file:

<?php
include 'config.php';

if(!isset($_SESSION['login_user'])) {
  header("location: login.php"); # redirect back to login page
}
guradio
  • 15,524
  • 4
  • 36
  • 57
G Y
  • 21
  • 1
  • 5
  • 1
    **WARNING**: When using `mysqli` you should be using [parameterized queries](http://php.net/manual/en/mysqli.quickstart.prepared-statements.php) and [`bind_param`](http://php.net/manual/en/mysqli-stmt.bind-param.php) to add any data to your query. **DO NOT** use string interpolation or concatenation to accomplish this because you have created a severe [SQL injection bug](http://bobby-tables.com/). **NEVER** put `$_POST`, `$_GET` or data *of any kind* directly into a query, it can be very harmful if someone seeks to exploit your mistake. – tadman Nov 28 '19 at 00:07
  • 1
    **WARNING**: Writing your own access control layer is not easy and there are many opportunities to get it severely wrong. Please, do not write your own authentication system when any modern [development framework](https://www.cloudways.com/blog/best-php-frameworks/) like [Laravel](http://laravel.com/) comes with a robust [authentication system](https://laravel.com/docs/master/authentication) built-in. At the absolute least follow [recommended security best practices](http://www.phptherightway.com/#security) and **never store passwords as plain-text** or a weak hash like **SHA1 or MD5**. – tadman Nov 28 '19 at 00:08
  • Consider using `VARCHAR(255)` as a default general-purpose string-type field and only override this with longer or shorter constraints if you have a compelling reason. Many MySQL installations will silently truncate any data which doesn’t fit, resulting in lost data, user complaints, and other serious issues. Names and email addresses are quite frequently surprisingly long, so accommodating these is important. – tadman Nov 28 '19 at 00:08
  • This is for a school project, and we haven't learned much web data security stuff yet besides "use $_POST and not $_GET." Are these security problems the reason why the login PHP isn't working? If not, please explain the issue with my login.php functionality. – G Y Nov 28 '19 at 04:02
  • 1
    It's partially a security issue, and don't diminish how important that is even for academic projects. You must learn to do it right to build good habits out of the gate. Secondly placeholder values make it much, much harder to screw things up by accident, saving you time and hassle. – tadman Nov 28 '19 at 04:33
  • We were specifically told to not use external authentication systems -- we have to code our own. Given that, can you tell me why mine's not working? – G Y Nov 28 '19 at 04:41
  • A) Use placeholder values. B) [Enable exceptions](https://stackoverflow.com/questions/14578243/turning-query-errors-to-exceptions-in-mysqli). C) At the absolute least use [`password_hash`](https://www.php.net/manual/en/function.password-hash.php) and [`password_verify`](https://www.php.net/manual/en/function.password-verify.php). D) Use `VARCHAR(255)` to have enough room to store all the data, not just bits of it. Note you're not actually checking the password as it stands. – tadman Nov 28 '19 at 05:30

0 Answers0