Course Banner

JWT Authorization

Authentication vs. Authorization

Did you notice in the previous activity that the word "authenticate" was used, but not "authorize" or "authorization"? You may ask, "What's the difference?" That is a good question!

Authentication

In the previous activity you followed a process where the client provided data (email address and password) which was sanitized and validated. Once the data was deemed safe, the email address was used to see if a matching email was found in the database from registered accounts. If so, the stored hash of the password was used and a comparison process carried out to see if the provided password, once hashed, matched the one stored in the database. If all of this was "true", then we are said to have "authenticated" the user - confirmed that what was sent matched data that was already stored.

Authorization

As a result of a successful authentication, a JWT token was created, which includes all the account data, except for the hashed password. The token was placed in a cookie and is automatically sent to the browser when the account management view is delivered. This token, carried by the cookie, will continue to be sent back and forth between the client's browser and the server, until one or the other of them expires. Each time it arrives at the server, the token can be checked and used as a "ticket" to enter areas of the site, that would otherwise be "off limits". In other words, it "authorizes" them to enter areas that they would not be able to if they did not have the token.

Video Overview

The video provides a general overview of the activity, but does not contain the detail needed to complete each process. Watch the video to obtain a general idea, but follow the written steps to complete the activity. This is the Transcript of the video.

Implementation

With some explanation out of the way, let's add the functionality to make authorization a reality. As in previous situations, this function is "Middleware". Meaning that it operates between the request and response objects. Once written, the function will be processed after the request object has arrived at the server and before the response object returns anything to the client.

  1. Find and open the utilities > index.js file.
  2. Scroll to the bottom of the file and create some blank lines between the last function and the module.exports statement.
  3. Add the following function:
    /* ****************************************
     *  Check Login
     * ************************************ */
     Util.checkLogin = (req, res, next) => {
      if (res.locals.loggedin) {
        next()
      } else {
        req.flash("notice", "Please log in.")
        return res.redirect("/account/login")
      }
     }
  4. An Explanation

    • Lines 1-3 - a comment explaining the function.
    • Line 4 - creates the function and assigns it to the "Util" object with a name of "checkLogin". Passes in request, response and next as parameters.
    • Line 5 - an "if" check to see if the login flag exists and is "true" in the response object.
    • Line 6 - allows the process of the application to continue by using the "next()" function.
    • Line 7 - ends the "if" and begins an "else" block.
    • Line 8 - create a flash message.
    • Line 9 - redirects to the login route, because the login flag does not exist.
    • Line 10 - ends the "else" block.
    • Line 11 - ends the function.
  5. Examine the code and ensure that no warnings or errors are present.
  6. Save the file.

Add to Route

Currently, we have a check to determine if the JWT token valid which is used with every route. We just added a second check, to see if the client is logged in. Think of a ticket taker checking to see if your ticket is for the correct day and time. It is general in nature, so should only be used for gaining access to general locations which should be authorized. It is NOT checking for anything specialized. Currently, we only have one such location, the account-management route.

  1. Find and open the routes > accountRoute file.
  2. Locate the default "/" route, that will trigger the process to deliver the account-management view. (You and your learning team were to write this route as part of the exercise found in a previous activity).
  3. Between the route indicator "/" and the controller function call (e.g. accountController.buildManagement), add the middleware function you just wrote - utilities.checkLogin.
  4. When done, the route could look like this:
    router.get("/", utilities.checkLogin, utilities.handleErrors(accountController.buildManagement))
    Your function in the controller may be named something different. Use your name, not the one shown in the example.
  5. Examine the code and ensure that no warnings or errors are present.
  6. Save the file.

Time to test

  1. Ensure that all files are saved.
  2. In a VSC terminal, run the server - type pnpm run dev, press "Enter".
  3. Open a browser tab and attempt to gain access to the account-management view by manipulating the URL, like this: localhost:5500/account/
  4. You should be re-routed to the login page and see the flash message.
  5. If you are not sent to the login view, check the cookies. If the JWT cookie exists, delete it. Then try getting to the account management view again.
  6. Register three new accounts with the following information using your registration form:
    1. account_firstname: Basic
      account_lastname: Client
      account_email: basic@340.edu
      account_password: I@mABas1cCl!3nt
    2. account_firstname: Happy
      account_lastname: Employee
      account_email: happy@340.edu
      account_password: I@mAnEmpl0y33
    3. account_firstname: Manager
      account_lastname: User
      account_email: manager@340.edu
      account_password: I@mAnAdm!n1strat0r
  7. Save these accounts' information as you will be using it often in the future.
  8. Login to your database and change the account_type of the Employee account to "Employee".
  9. Change the account_type of the Manager account to "Admin".
  10. Login as "Basic Client". The account-management view should appear indicating you are logged in. Check the jwt cookie using the Web Development Tool > Cookies tab > View Cookie Information. Look at the value of the token, perhaps writing down the last 4 or 5 characters of the token. Delete the cookie and close the tab where you were looking at the cookie information.
  11. Login as either the "Happy Employee" or "Manager User". Again, you should be directed to the account-management view. Examine the value of the jwt token in the cookie. The jwt token value should be different from that of the first token. This is because the payload is different.

Conclusion

Assuming that everything worked, you can log in and the cookie containing the token is set and sent to the browser, and it is checked to allow the client access to the account-management view, then the authentication is working. Notice the general nature of the check. All three accounts are allowed access, even though all three are different types of account. Yay! Do a happy dance. If not, then talk to your learning team, the TA or the professor. But, get it working before moving on to the enhancement.