⚠️ This lesson is retired and might contain outdated information.

Connect a Front-End to a Secure API using JWTs

Joel Lord
InstructorJoel Lord
Share this video with your friends

Social Share Links

Send Tweet
Published 6 years ago
Updated a year ago

In this lesson, we add the login form to a single page application and we pass our tokens to the API. Should the token be valid, we will have access to the data from the secure endpoint in the API.

Instructor: [00:00] To connect our front-end to our API in our authentication server, we first need the URL for those. In this case, I started the API on port 8888, so we can add that to a constant.

[00:18] The authentication server is also running a local host on port 3000. Let's add this to the auth URL constant. We will keep the access token from our authentication server stored in memory. For now, we can initialize the access token constant to undefined.

[00:36] Let's take a look at the front-end that was pre-built for us. There was a button labeled public, and another labeled private. They will both update the jumbotron beneath it with the response that we're getting from our ajax calls.

[00:50] The image of the Cat will also be update with the status quo that we are getting from the server. For the UI updates, the helper functions are already created. We will focus on the actual logic in here.

[01:03] For now, none of the buttons do anything. Let's go back to our code. Headline button here is the button labeled public. We will start by doing a fetch to our public resource, which is on the API server at the /resource endpoint.

[01:23] Fetch returns a promise, so we will use the then method with the response and we will return the result of response.text. This will return the actual data in text format to our next chain.then method.

[01:40] Finally, we can use the UI update object and the alert box method to update the jumbotron with the data from our response.

[01:51] We are ready to test our first ajax call. Clicking on the public button shows the public resource. You can see this message. That works.

[02:00] Let's now move on to the second button, the one labeled private. In here, we will do a very similar code. We start by doing a fetch to the API url and /resource/secretURL. We return the .text from the response and we update our jumbotron the same way we did for the public button.

[02:25] If we go and test this, we will see that we are getting an error message instead of the actual response that we are expecting. That is due to the fact that we have not passed in an authorization header.

[02:35] Now that we know that this URL will sometimes return us an error code, let's update our http Cat with the response that we get from the server. Before we return the parse body of our response, we can use the UIUpdate.updateCat method with the response status quo.

[02:52] If we try this again, we see that we're getting a 401, which is the error code for a non-authorized access.

[03:00] Before we can pass in a token with our request, we will need to authenticate. Let's go the login button click event listener and do a post request to our authorization server.

[03:12] In here, we will do a request to the authURLs/login endpoint. We will also specify a few options to our request. First, this is not a get, so we will need to add method post, then we need to specify the headers to tell our server that we are sending content of type application/json.

[03:31] We need to specify that we are accepting under response of type application/json. The body of our request will be the username and password in JSON format provided by our UI update helper object.

[03:47] We will update our httpCat with the response status quo. If we get a 200, we will send the JSON object from our response to the next promise. If our response was anything else, we will use the text of the response.

[04:01] We can then chain with another event and verify the presence of an access token. If we have one, we can store the access token in the access token variable that we defined in the beginning.

[04:22] We can also overwrite the content of data with access token called in and the content of the token. If we have an access token, this means that we are logged in, so we can use the UIUpdate.login method to update our UI.

[04:43] Finally, we will update our jumbotron with our data variable. Let's try this out.

[04:54] If we click on login, we have a module asking for our credentials. If we enter nothing, we are getting a 400 bad request error with the message, "You need a username and password."

[05:05] Let's try to enter a username admin, and its valid password. This time, we are getting a 401 unauthorized with the message, "User not found." Now, if we use the right username and password combination, we are getting an access token.

[05:20] If we copy and paste the access token in jwt.io, we can see the content of the token. It has the right username.

[05:30] Back to our application, if we click on private, we are still getting a "No authorization token was found" error message. That's because we are still not passing a token with our request.

[05:43] Back to the secret button, let's start by defining our headers. We can start by initializing with an empty object, then we test to see if access token is still undefined or if we have an access token toward there.

[05:58] If we do, we can specify the headers. We will add an authorization with the value of bearer followed by a space, and then access token.

[06:13] Now, we can add those through our request as a second argument to our fetch. Let's test this out. Start by refreshing the app, and then log in using admin and the valid password.

[06:27] Now, if you click on private, you'll get the secret resource. You should be logged in to see this message. We now have access to our secret resource.

[06:36] Finally, we will need a way to log out. If we go to the logout button click event handler, we can simply reset our access token to undefined and use the UI update logout method.

[06:51] One last time to our application, and we can now log in using a valid credential and get access to the private button. Now, if you log out and try the private button again, you're getting the 401 error with the "No authorization token found" error message again.

[07:09] That's it. You now have a front-end that access both public and private data from an API using a JSON web token.

Bhuvnesh babu
Bhuvnesh babu
~ 6 years ago

Please, add instructions to run index.js/html on server. I could run API server and authentication server on separate ports but not sure how to run "index.html" on server. Thanks.

Bhuvnesh babu
Bhuvnesh babu
~ 6 years ago

I got the answer:$ npm install http-server ( in the same directory as project is otherwise you have to browse the path) To run the server: $http-server ( by default it will execute on port 8080) then in the browser http://localhost:8080/index.html

Joel Lord
Joel Lordinstructor
~ 6 years ago

Yes, you can use any regular web server to serve the index.html file. I personally use "serve" (also available on npm).

Jack
Jack
~ 6 years ago

You make a HUGE jump here from working with an API in Postman, to hooking it up to a front end. You offer no explanation of how to get that all set up. Big oversight.

Jack
Jack
~ 6 years ago

For those that want to do this... first grab the index.html file he's using in the video from his github account: https://raw.githubusercontent.com/joellord/egghead-auth-course/master/lesson7/end/index.html

Then create a separate express server file that serves the index.html file, something like this.

const express = require("express")
const bodyParser = require("body-parser")

const app = express()
const PORT = process.env.PORT || 4321

app.get("/", (req, res) => {
  res
    .status(200)
    .sendFile(__dirname + "/templates/index.html")
})


app.listen(PORT, () => {
  console.log(`Server is running on Port ${PORT}`)
})

Then add a new script to your package.json, something like:

"serve": "node frontendServer.js"

That should bridge the gap here,

You will then need to run both servers. One managing the index.html on the front end, and the other for the API.

Pretty shocking that they missed this out on paid for premium content.

Jack
Jack
~ 6 years ago

You also need to set up serving of static files as an express middleware

app.use(express.static(__dirname + '/public')

AND you also need to have the UI-Updates file which is also on the github for this course.

Seriously guys... this is a disgrace. You're taking money off people for half finished courses. Sort it out. Quality control.

Jack
Jack
~ 6 years ago

Also, the fetch request for logging in uses the wrong variable... uses AUTH_URL instead of API_URL ... means the frontend is currently fetching authorization from itself lol. Make sure its API_URL

Francis  Emefile
Francis Emefile
~ 6 years ago

Jason Watmore's blog has an article on how to use http-server to feed static pages:

http://jasonwatmore.com/post/2016/06/22/nodejs-setup-simple-http-server-local-web-server

If you haven't installed http-server, you can by: npm install -g http-server

Then, open command prompt on the project folder, and start the server with: http-server

Finally, use http://localhost:8080/index.html to access the page.

N.B: Make sure to read the port that is supplied in the command prompt when the server starts. This is displayed under Available on:

RC Maples
RC Maples
~ 6 years ago

With the jump from setting up the backend only and testing with Postman to having a frontend hooked up make this lesson and tutorial a bit useless.. Even with the comments above giving insight in how to bring up and serve the index.html page the instructor should put this in the tut. I downloaded the code from the github repo's 'start' folder and cannot launch the code via node at all. @Joel's comment from a month ago is too vague to understand how to hook up the front end to the backend and it feels like a massive leap from the previous lesson to the current code in this lesson. Why are good JWT tuts so hard to find. :(

Hatem
Hatem
~ 6 years ago

Unfortunately, I think this was more of a promotional video to promote Auth0 than to properly illustrate how to do it without a framework etc... as was claimed in the beginning. From what I understand, we have 3 things: Auth Server, Resource Server, and Client.

Auth Server is the example in one of the videos that had the "/login" example that used the "jwt.sign(...)" to sign a jwt token.

Resource Server is the example that used the "/resource" route to serve the data etc...

Client which he did not show is to run the html. If you're using VS Code you can use the live server to run that which will probably run on port 5500 by default. This way you won't have to setup a third server if you're not interested in doing that to run the example.

Tyler
Tyler
~ 5 years ago

This lesson isn't too hard to follow if you have the basic concepts of JWT down. Installing Visual Studio Code and using live server is a quick way to host the static file.

Hatem
Hatem
~ 5 years ago

He wasn't organized, he jumped around from server to server without letting viewers know. I had an idea of what he was doing from my spring/java background. Anyhow, if you're interested in the cleaned up version of the code I'll share it with you. I have it somewhere on my system and I'll dig it up if you'd like to see a functioning version of it.

Hafeez Syed
Hafeez Syed
~ 4 years ago

why running API_URL and AUTH URL on different ports? In the previous lessons they were all runnig on same port.

Joel Lord
Joel Lordinstructor
~ 4 years ago

The API server and the Auth server should both be running at the same time. Hence, they have to run on different ports in order to work simultaneously.

Mohammed A
Mohammed A
~ 4 years ago

@Joel Lord please can you address the comments on the missing tutorial context? You seem to have skipped over those

Markdown supported.
Become a member to join the discussionEnroll Today