Skip to content

Student Listing: Adding User Logins - Login

Creating a Login Page with the Usual Bootstrap Template with a Card

Let's create a login.php script using a Bootstrap template and add a Card for our content with a header for the title of the page, along with Bootstrap's client side JavaScript validation code:

login.php - Student Listing: Using Bootstrap Template with Card and Client Side Validation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<!DOCTYPE html>
<?php
    session_start();
    require_once('pagetitles.php');
    $page_title = SL_LOGIN_PAGE;
?>
<html>
  <head>
    <link rel="stylesheet"
          href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"
          integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
          crossorigin="anonymous">
    <title><?= $page_title ?></title>
  </head>
  <body>
    <div class="card">
      <div class="card-body">
        <h1><?= $page_title ?></h1>
        <hr/>
      </div>
    </div>
    <script>
        // JavaScript for disabling form submissions if there are invalid fields
        (function () {
            'use strict';
            window.addEventListener('load', function () {
                // Fetch all the forms we want to apply custom Bootstrap validation styles to
                var forms = document.getElementsByClassName('needs-validation');
                // Loop over them and prevent submission
                var validation = Array.prototype.filter.call(forms, function (form) {
                    form.addEventListener('submit', function (event) {
                        if (form.checkValidity() === false) {
                            event.preventDefault();
                            event.stopPropagation();
                        }
                        form.classList.add('was-validated');
                    }, false);
                });
            }, false);
        })();
    </script>    
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
            integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
            crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"
            integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut"
            crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"
            integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k"
            crossorigin="anonymous"></script>
  </body>
</html>

NOTE: Notice that we made a call to session_start() at the top of the script. Also notice the setting and usage of our page title ($page_title = SL_LOGIN_PAGE;) from our pagetitles.php constants script.

Self Referencing Page with Three Possible Different Outputs

When a user navigates to the login.php script, there are three possible states a the user can be in:

  • Not logged in
  • Just logged in (i.e. they selected the Login button on the login.php page)
  • Already logged in

If a user is not logged in we want them to see this form:

If a user selects the Login button on the login.php page, we want them to be redirected to the main Student Listing page:

And if a user navigates to the login.php script after they are already logged in, we want the login.php script to display:

Since we are using Session variables to achieve this, you'll need to add the following conditional statements directly below the <hr/> element:

login.php - Student Listing: Three Possible Conditions

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
...
<h1><?= $page_title ?></h1>
<hr/>
<?php
// Not logged in and just submitted form
if (empty($_SESSION['user_id']) && isset($_POST['login_submission']))
{

}
if (empty($_SESSION['user_id'])): // Not logged in
?>
<?php
elseif (isset($_SESSION['user_name'])): // Already logged in
    echo "<h4><p class='text-success'>You are logged in as:
          <strong>{$_SESSION['user_name']}</strong>.</p></h4>";
endif;
?>
...

Notice above, that the display output is already filled in if the user is already logged in.

Let's add the self referencing form for logging in users if they're not already logged in. Add the following code into the if (empty($_SESSION['user_id'])): condition:

login.php - Student Listing: Display Form if User not Logged in

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
...
if (empty($_SESSION['user_id'])):
?>
  <form class="needs-validation" novalidate method="POST"
      action="<?= $_SERVER['PHP_SELF'] ?>">
    <div class="form-group row">
      <label for="user_name" class="col-sm-2 col-form-label-lg">User
          Name</label>
      <div class="col-sm-4">
        <input type="text" class="form-control" id="user_name"
            name="user_name" placeholder="Enter a user name"
            required>
        <div class="invalid-feedback">
            Please provide a valid user name.
        </div>
      </div>
    </div>
    <div class="form-group row">
      <label for="password" class="col-sm-2 col-form-label-lg">Password</label>
      <div class="col-sm-4">
        <input type="password" class="form-control"
            id="password" name="password"
            placeholder="Enter a password" required>
        <div class="invalid-feedback">
            Please provide a valid password.
        </div>
      </div>
    </div>
    <button class="btn btn-primary" type="submit"
        name="login_submission">Log In
    </button>
  </form>
<?php
elseif (isset($_SESSION['user_name'])):
...

Logging the user in

When logging the user in, there are a few things we need to do:

  • Grab the fields from the form
  • Validate the form fields
  • Verify the user exists in the database, or display an appropriate error
  • Verify the user's password hashes, or display an appropriate error
  • Set the Session variables for the logged in user
  • Redirect the user to the Student Listing page

Add the following code within the if (empty($_SESSION['user_id']) && isset($_POST['login_submission'])) condition:

login.php - Student Listing: Logging user in

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
...
// Not logged in and just submitted form
if (empty($_SESSION['user_id']) && isset($_POST['login_submission']))
{
    // Get user name and password
    $user_name = $_POST['user_name'];
    $password = $_POST['password'];

    if (!empty($user_name) && !empty($password))
    {
        require_once('dbconnection.php');

        require_once('queryutils.php');

        $dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME)
                or trigger_error(
                'Error connecting to MySQL server for' . DB_NAME,
                E_USER_ERROR );

        // Check if user already exists
        $query = "SELECT id, user_name, password_hash, access_privileges, studentListing_id "
                . "FROM user WHERE user_name = ?";

        $results = parameterizedQuery($dbc, $query, 's', $user_name)
                or trigger_error(mysqli_error($dbc), E_USER_ERROR);

        // IF user was found, validate password
        if (mysqli_num_rows($results) == 1)
        {
            $row = mysqli_fetch_array($results);

            if (password_verify($password, $row['password_hash']))
            {
                $_SESSION['user_id'] = $row['id'];
                $_SESSION['user_name'] = $row['user_name'];
                $_SESSION['user_access_privileges'] = $row['access_privileges'];
                $_SESSION['user_student_listing_id'] = $row['studentListing_id'];

                // Redirect to the home page
                $home_url = dirname($_SERVER['PHP_SELF']);
                header('Location: ' . $home_url);
            }
            else
            {
                echo "<h4><p class='text-danger'>An incorrect user name 
                      or password was entered.</p></h4><hr/>";
            }
        }
        else if (mysqli_num_rows($results) == 0) // User does not exist
        {
            echo "<h4><p class='text-danger'>An account does not exist for this username:"
                . "<span class='font-weight-bold'> ($user_name)</span>. "
                . "Please use a different user name.</p></h4><hr/>";
        }
        else
        {
            echo "<h4><p class='text-danger'>Something went terribly wrong!</p></h4><hr/>";
        }
    }
    else
    {
        // Output error message
        echo "<h4><p class='text-danger'>You must enter both a user name and password.</p></h4><hr/>";
    }
}
...

Complete Code Listing

login.php - Student Listing: Complete Code Listing

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
<?php
    session_start();
    require_once('pagetitles.php');
    $page_title = SL_LOGIN_PAGE;
?>
<!DOCTYPE html>
<html>
  <head>
    <title><?= $page_title ?></title>
    <link rel="stylesheet"
        href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"
        integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
        crossorigin="anonymous">
  </head>
  <body>
    <div class="card">
      <div class="card-body">
        <h1><?= $page_title ?></h1>
        <hr/>
        <?php
        if (empty($_SESSION['user_id']) && isset($_POST['login_submission']))
        {
            // Get user name and password
            $user_name = $_POST['user_name'];
            $password = $_POST['password'];

            if (!empty($user_name) && !empty($password))
            {
                require_once('dbconnection.php');

                require_once('queryutils.php');

                $dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME)
                        or trigger_error(
                        'Error connecting to MySQL server for' . DB_NAME,
                        E_USER_ERROR );

                // Check if user already exists
                $query = "SELECT id, user_name, password_hash, access_privileges, studentListing_id "
                        . "FROM user WHERE user_name = ?";

                $results = parameterizedQuery($dbc, $query, 's', $user_name)
                        or trigger_error(mysqli_error($dbc), E_USER_ERROR);

                // IF user was found, validate password
                if (mysqli_num_rows($results) == 1)
                {
                    $row = mysqli_fetch_array($results);

                    if (password_verify($password, $row['password_hash']))
                    {
                        $_SESSION['user_id'] = $row['id'];
                        $_SESSION['user_name'] = $row['user_name'];
                        $_SESSION['user_access_privileges'] = $row['access_privileges'];
                        $_SESSION['user_student_listing_id'] = $row['studentListing_id'];

                        // Redirect to the home page
                        $home_url = dirname($_SERVER['PHP_SELF']);
                        header('Location: ' . $home_url);
                    }
                    else
                    {
                        echo "<h4><p class='text-danger'>An incorrect user name 
                              or password was entered.</p></h4><hr/>";
                    }
                }
                else if (mysqli_num_rows($results) == 0) // User does not exist
                {
                    echo "<h4><p class='text-danger'>An account does not exist for this username:"
                        . "<span class='font-weight-bold'> ($user_name)</span>. "
                        . "Please use a different user name.</p></h4><hr/>";
                }
                else
                {
                    echo "<h4><p class='text-danger'>Something went terribly wrong!</p></h4><hr/>";
                }
            }
            else
            {
                // Output error message
                echo "<h4><p class='text-danger'>You must enter both a user name and password.</p></h4><hr/>";
            }
        }
        if (empty($_SESSION['user_id'])):
        ?>
          <form class="needs-validation" novalidate method="POST"
                action="<?= $_SERVER['PHP_SELF'] ?>">
            <div class="form-group row">
              <label for="user_name" class="col-sm-2 col-form-label-lg">User
                  Name</label>
              <div class="col-sm-4">
                <input type="text" class="form-control" id="user_name"
                    name="user_name" placeholder="Enter a user name"
                    required>
                <div class="invalid-feedback">
                    Please provide a valid user name.
                </div>
              </div>
            </div>
              <div class="form-group row">
                <label for="password" class="col-sm-2 col-form-label-lg">Password</label>
                <div class="col-sm-4">
                  <input type="password" class="form-control"
                      id="password" name="password"
                      placeholder="Enter a password" required>
                  <div class="invalid-feedback">
                      Please provide a valid password.
                  </div>
                </div>
              </div>
              <button class="btn btn-primary" type="submit"
                  name="login_submission">Log In
              </button>
          </form>
        <?php
        elseif (isset($_SESSION['user_name'])):
            echo "<h4><p class='text-success'>You are logged in as:
                  <strong>{$_SESSION['user_name']}</strong>.</p></h4>";
        endif;
        ?>
      </div>
    </div>
  <script>
      // JavaScript for disabling form submissions if there are invalid fields
      (function () {
          'use strict';
          window.addEventListener('load', function () {
              // Fetch all the forms we want to apply custom Bootstrap validation styles to
              var forms = document.getElementsByClassName('needs-validation');
              // Loop over them and prevent submission
              var validation = Array.prototype.filter.call(forms, function (form) {
                  form.addEventListener('submit', function (event) {
                      if (form.checkValidity() === false) {
                          event.preventDefault();
                          event.stopPropagation();
                      }
                      form.classList.add('was-validated');
                  }, false);
              });
          }, false);
      })();
  </script>
  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
          integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
          crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"
          integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut"
          crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"
          integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k"
          crossorigin="anonymous"></script>
  </body>
</html>