Using Auth Tokens in the Client

In the last chapter we added JavaScript code to the client which allows the user to login and create an account using the API server.  In both cases, the API server returned an authorization token in the HTTP response which was saved in the browsers storage and the user was redirect to the main web page.  In this chapter we’ll add JavaScript code to the main web page that will allow the user to retrieve their account information, delete their account, and log out.

Let’s jump in.

Add HTML Elements to the Main Page

On the main web page, we need to provide HTML elements that the user can click on when they wish to see their account information, request that their account be deleted, and log out.  I have used a boostrap dropdown menu in my app, but you are free to use any mechanism you like.

However you decide to implement this functionality, you’ll need to provide id attributes for each of the interactive elements and take note of the values that you give to these id attributes.  We’ll need them in the JavaScript code.

Again you will need elements that the user can click on that allows the user to:

  • view their account information
  • delete their account
  • log out of the app

You’ll also need an HTML element on the main page that you can insert text into (e.g. a <p> element or a <div>) and provide the element an id attribute as well.

Add a JavaScript File

Add a file named user.js to your public/js directory.  This file will register the click event handlers for each of the clickable HTML elements.

Add a Script Tag to the Main Page

Add the following script tag in the <head> element of your main web page to load the public/js/user.js JavaScript file.

<script defer src="/js/user.js"></script>

Add Code to Get Account Information

Below is the code that I use to register a click event handler for my dropdown menu item that reads “Display account”.  You’ll likely need to make three changes to the code.

  1. My menu item has an id attribute set to displayAccountItem.  If the id of your clickable item is different, please modify the id on line 1.
  2. Replace <<your-API-server-domain>> on line 9 with the domain name of your API server.
  3. I write the data received from the API server as text in an element with an id set to contentArea.  If your element has a different id value, make the necessary changes to line 24.

Please copy the code shown below to your user.js file, make the changes discussed above, and read the explanation of the code in the next section.

const displayAccountItem = document.querySelector("#displayAccountItem")

displayAccountItem.addEventListener("click", async(e) => {
    e.preventDefault()

    const token = localStorage.getItem("token")

    //const url = "http://localhost:3001/users/me"
    const url = 'https://<<your-API-server-domain>>/users/me'

    const options = {
        method: "GET",
        headers: {
            Authorization: `Bearer ${token}`,
        },
    }

    let response = await fetch(url, options)

    if (response.ok) {
        if (response.status === 200) {
            const data = await response.json()

            const contentArea = document.querySelector("#contentArea")
            contentArea.innerHTML = `Name: ${data.name} <br>Email: ${data.email}`
        }
    } else {
        console.log("HTTP-Error: " + response.status)
    }
})

Explanation of the Code

On line 1 we use document.querySelector() to retrieve the clickable node from the DOM.

On lines 3-30 we register the handler for the click event.

Line 4 prevents the click event’s default action.  This is necessary if, for example, the HTML element is a <a> element that would, by default, redirect the user to another page.

Recall that when the user logs in or creates an account, the authorization token is placed in the browser’s local storage.  We retrieve the authorization token from the browser’s local storage on line 6 and store it a constant named token.

On lines 8 and 9 we create a constant to hold the url of the API server.

On lines 11-16 we create an object that we’ll pass to fetch(). This object sets the HTTP method to GET, and uses template literal syntax on line 14 to place the authorization token in the Authorization header of the HTTP request.

We call fetch() on line 18, passing to it both the URL of the API server and the options object.

On line 20 we check if fetch() received a successful response with a status in the range 200-299 by calling response.ok.

If successful and the status is equal to 200 (line 21), we convert the body of the response to a JSON object and display the data received as text on the web page (lines 22-25).

If fetch() was not successful, then on line 28, we print an error to the console.

Add Code for Delete Account and Logout

As an exercise, add code that allows the user to delete their account and logout.  The code is very similar to the code shown above.

When a user chooses to delete their account, it is a good idea to use a modal dialog box that prompts the user to confirm or cancel their request.  The inclusion of modals is beyond the scope of this course so I won’t review it here.  For this app, you are free to experiment with modals, or not.

If the user is successful in deleting their account or logging out, redirect the user to the app’s initial page.

Test Locally, Deploy to Heroku, and Test Again

When a user is logged in, all three capabilities (view account info, delete account, and logout) should succeed. If not, then there is an error in your code that will need debugging.

If the user successfully delete’s their account, check the API database to be certain the document was deleted.

© 2022 – 2024, Eric McGregor. All rights reserved. Unauthorized use, distribution and/or duplication of this material without express and written permission from the author is strictly prohibited.