 Hey folks, it's Ben Deck right here from AltZero. Join me for the next 20 minutes or so and we're going to take the Express Node.js app that we wrote in the first two episodes and we're going to add some route specific authentication and we're also going to create a separate Express API with public and private routes. It's a slightly longer video than usual so feel free to use the time codes below to jump to the part that's more specific to you, otherwise feel free to watch the whole show and I'll look forward to you joining me. Let's get into it. In the first two episodes of this series we created a Node.js Express web application. We added EJS as a templating mechanism and added AltZero for authentication so that we could log in and get a page similar to this one where we can see the profile picture and the name of the person who's logged in. If you want to revisit those or you miss out on those, click on the link up in the top right hand corner and have a look at those maybe before you've watched the rest of this video. If you're okay to continue, let's carry on and what we want to do today is to create a second page in our web application that forces login at the moment the home page can be viewed when you're not logged in, we just don't see the user information so we want to create a secured path within the other web application that you have to be logged in for and we're also going to create a simple Express-based API that we can connect to from our web application and we're going to create some public and private endpoints in there as well, again integrating that with AltZero. Let's get cracking with the web application first. What I want to do is create a second page that enforces authentication. Over here we can see the main app.js that we wrote last time. The routing is all handled by this index router which is defined in the routes index.js and we only have one handler at the moment. If we make a request for the home page, we basically render the index template so let's duplicate this and we'll create a new URL within the web application and we'll call this secured and we're going to use a different template. We'll create a template called secured and I'm also going to change the title just so that we can see that coming through so we'll call this one secure page and they're the only changes I'm going to make to the routing at the moment. Hit save and then we'll come over. This is our view index.js. This is the template for the home page. I'm going to hit save as and we're going to call this secured so that we've got the template for the new page that we've just created. I'm also just going to reopen the index page because what I want to do is I no longer want to show this photo on the home page. I only want to show it on the secured page so I'll just come in here within the index page. I'll just come in here and we'll delete this one. If we hit save now and we hit refresh over here we'll see that the photo's gone. Now I could type in secured as a URL up here but let's add some menu items in so on the index template here I'm going to copy this line and we'll paste this in a couple of times. I noticed from last time we had a couple of extra quotes in here so I'll just clean that up. What we want to do is have a link to the home page and a link to the secure page. This will go to secured and this is just the route. If I hit save over here and we hit refresh then over on the right we can see the links have come in at the top. Clicking home takes your home page secure takes you to the secure page and we can see that the photos come back because that's in the secure template. The navigation however hasn't copied through because each of these files has its own navigation and rather than just copying and pasting these two lines into the secure template what I'm going to do is just break this out into a partial so that we can include that in future pages anywhere we like. So I'm going to create a new file under views and in fact we'll put this in a partials directory. We'll call this nav.ejs and we'll just paste that in here. Hit save. We can close that again now and then rather than outputting the nav in here this way we can use the ejs syntax to include partial's nav and if we copy this and go into our secure page template and paste that in here. Save both of these by now refresh our secure page we get the full menu at the top and when I switch between the two pages our navigation is now pulled in from our partial. This is much nicer and cleaner to have a look at. Now the thing is at the moment if I log out and I click on the secure page I'm still getting to the secure page it's obviously not showing any details because the user object doesn't exist but we actually want to make this force people to log in. So if we jump back over to the index page here what we can do is we can provide an extra parameter to this this endpoint handler to require that authentication and the way we can do that is by calling in the requires auth object from and then here we need to require the express open ID connect module that we used initially for the authentication. Now we can also require authorization and in here we're going to still authentication rather requiring auth in order to render this and here we simply say requires auth as a second parameter. Now if I hit save and we come over to the secure page and hit refresh it's going to redirect us to the login page so we have to be logged in for this one. If I just go back before I log in we go on the home page and we refresh that that's not a problem that's still publicly available. So we'll click on secure text is over to the login page and once I'm logged in again it'll render the secure page that we had before with the information that is pulled out of my ID token. The next thing I want to do is create the express API. So what we'll do is we'll take this in small steps first we'll create an API with a public endpoint and we'll pull that information into our web application for display and then we'll continue down the path of adding authentication to the endpoints within the API. For the API I have a blank directory over here called express API. And the first thing we need to do is install express itself. That's going to allow us to use express as the API rendering a handling mechanism. And in the same way as we did for the web application in the first two episodes, rather than running node manually every time and having to restart it when we make change to the files, I'm going to install the dev dependency here of node mon. This is going to allow node one to monitor the files when we make us change node mon will restart node automatically. And we don't have to remember to restart it every time we want to see a change in our application. In order to use node mon, we need to come into the packages.json file. And we need to define a new script. The script we want is the start script. And when we run MPM start, we want it to run node mon. And app.js is going to be our entry script. So now we can come in here and create app.js. And again, very rudimentary, we're going to define express, express there. And then we're going to define a new app, which is basically the instantiation of express. And we want to have a single endpoint to start with. This is going to be the public endpoint. So app.get. And if we get a request for the public endpoint, we are going to call this function that receives the request and the response. And the way we're going to handle this request is just to do a response.json to return some data. And for now, we're just going to say type is public. Finally, we need to start the app itself. So we need to listen on port. We'll use port 5000 for this one. The other application is running on port 3000. We'll run the API on port 5000. And now if we run MPM start down here, we can see it's now watching the files and it started the application. And if we open a new tab and we go to localhost port 5000 slash public, we get the response there, the json response of type is public. Okay, that's great. Let's now get it to display this information at the bottom of this secure page. So we'll flip back to the web application. And on the secure page itself, before I forget, we'll just output the data that we're going to get from the response. So for this, it's going to be a json response. So we're going to use json.springify. We'll pass in the data which we'll collect in a second and just a little bit of formatting. And I'm also going to wrap the whole thing here in a pre tag just to make it a bit easier to read on the page. So we'll just save that and then we'll come back into our index page here. So under the the secured endpoint here, we want to do a bit of work to get the data in. I always like to define the default just in case we're not able to receive information from the API. Maybe it's down, maybe our internet connection is broken. Could be a number of issues. So by default, we're going to create an empty object of data and then we can pass that data into the template. So if I save this now, we should see that come through the bottom there. Now what we want to do is actually get the data from the API though. So we're going to need to install another module. I like to use Axios for HTTP based requests. If you have another module you prefer to use, that's fine too. So I'll just stop the application down here and we'll install Axios. While that's happening, I'll come in and we'll pull Axios in at the top. That's happened. So I'm just going to start NPM, start the application again. So we've got our Axios handler there. So now what we can do is we can get an API response, which is going to be the result of, we're going to do an await on this one. So it's going to be the result of Axios.get and the endpoint that we're calling is HTTP localhost, what 5000 public. Now because we're doing an await here, we're going to have to make sure that the the handler function is an async function. So we'll just put an async in there and this could fail. So let's also wrap this in a try catch. I'm not going to do anything in the catch. We'll just catch it and if you want to do some error handling of your own, that's something that you can decide how you want to handle within your application. But in case it fails, we're just not going to do anything. If we do get an API response though, then we can say data is going to be equal to the data returned from the API response and that should now go into our application. So if I had to save on this and we had refresh over on this page here, we can see the type public is coming through. The web application is making a call to the API to receive that and then display it in the template. Right, next thing we want to do is to create a private endpoint on the API. So let's switch back over to the API code over here and again we're just going to simply copy and paste this. We'll create a private endpoint and we'll return type as private. Now if I just hit save and we come over here and change this to call private, we can see that response is coming through and if we come back into our main web application and we call private here instead, we get to save and refresh this page, we can see private is coming through. So that new endpoint is working well but of course it's not actually private. I'm able to make this call directly from a web browser and there's no authentication required. So we need to add some authentication into our API now. In order to do this we need to do a bit of configuration in the Auth0 dashboard and the reason for this is the Auth0 in previous episodes we set up to understand our web application. We now need it to understand information about the API so that it can then generate access tokens which will come to later in the video. You'll be able to generate those access tokens to allow anybody who's logged into our application to access the API. So if we jump over to the Auth0 dashboard here and head to the API section of our applications then you'll see that by default we get a definition here for the Auth0 Management API. What we need to do though is create a new API for our purposes. So we're going to create one called Express API. The identifier is generally a URI. It doesn't need to be but to keep consistency we generally use that. It also doesn't have to be the exact URI of your API but again just for reference purposes it makes it easier if that's what you put in here. So I'm going to keep with consistent practice and we'll do localhost port 5000. Create that one. Now on this page here we get to go straight with the quick starts again. I'm going to click on Node.js and what what you get here is basically a a complete app.js that you could just copy and paste and get going straight away. Obviously we've got some of these end points already in there and some of this configuration so I'm only going to copy out the bits that we need in order to configure our existing API to integrate with Auth0. So the first thing we need to do is to install a couple of extra modules so I'll just put those in there and we'll stop the application. So in PM install we want to add Express JWT and JWKS RSA. Yes. Essentially what Express JWT is providing us is a standards compliant way of receiving a JSON web token in the Barrett token the authentication headers of the request that comes into the API. This is not specific to Auth0. Any open ID compliant identity provider is going to issue JSON web tokens that can be interpreted and handled using the Express JWT library. The JWKS RSA library is allowing us because we're using RSA 256 as a signing algorithm for the the JSON web tokens that's a public private key based signing and in order to get the public key from the issuing authentication server the JWKS RSA library allows us to do that really easily and the way we do that if we switch back over here and look at this code is to define this JWT check and copy that line as well and then we'll go through that in here. So let's paste this in. So we're defining this JWT check which is a way of checking the JSON web token and we're basically saying that the secret is defined by using this JWKS URI again part of this JWKS RSA library saying this endpoint here will give you the public key from the identity provider so that you can use that to verify that the JSON web token hasn't been tampered or modified in transit. It's also defining here that the token is only valid if the audience is local host port 5000. This part here aligns with the configuration we put into Auth0 and then we also want to make sure that our Auth0 tenant is the issuer unless the token was generated by this issuer here we're not going to accept it and finally we're saying we will only accept tokens that are signed using RS256 hashing algorithms. This line 18 here basically tells the whole application to say you need to make sure that JWT check passes in order to render any pages. So let's hit save and we'll come back over here to the private page and we'll hit refresh. We need to restart npm. We'll hit refresh and we can see that we're getting a no authorization token was found and that's great. The only downside is that if we go back to our public page and hit refresh we're getting the same thing there and the reason for that is this line 18 where we say the whole application needs to use JWT check before proceeding. We only want this one endpoint here to have a check on it. So what I'm going to do is I'm going to copy this and we're going to pass that through as the second parameter. So this is something that needs to pass for this endpoint to be able to be rendered and then we can get rid of that from here because we want the public endpoint to still be publicly accessible. If I hit save now and we refresh this page over here we can see the public is still working and if we go back to the private and hit refresh it's still expecting a token. So we've now managed to secure the endpoint. If we come back over here and refresh this page we'll see that we're not getting any data through because the application is making a request for the private endpoint still but it's not providing that authentication information for the API to be able to be happy that it's able to return the information that's being requested. So let's jump back over to the web application and see what we can fix over here in order to get that header information through. We're making a request here to the private endpoint and in order to pass extra information through we provide a second parameter which is an object of information and in here we want to define some headers and the header we want to define is the authorization header and this is usually in the form of bearer and then whatever the token is that came through. We need to pull this information out when we log in so we're going to have to get a bit more information during the login process in order to get access to this access token. Once we have that we'll be able to use another method of the request OIDC so in the previous episodes we called request OIDC and use the is authenticated. We also pulled out the user. There's another part of the request dot OIDC called the access token and this here we can actually pull extra information out of so the information we're going to want from the access token is the token type and the access token itself. The token type in most cases is going to be bearer so that will be replaced in here and then the actual token itself goes next so presuming we can get these two bits of information out we'll now be able to pass this into the authorization header and that should solve this part of the problem. The next thing we need to do though is provide a mechanism for the web application to request the access token from Auth0 during the login process so I'm just going to save this and we're going to jump back into our main app and this is where we've got the main configuration for connecting to Auth0. We put a whole lot of these things into our environment variables in one of the previous episodes. We need to add a bit more information in so Auth0 is able to request that access token. By default it'll just get an ID token and a different kind of access token that just gives you a bit more information about the user. We want an access token that we can use with a third-party API. So one of the things we're going to need to pass in as well as the client ID as you can see here on line 11 is we need to pass in the client secret and we're going to define this again as an environment variable and the other bit of information we need I'll just paste in here we can go through. We need to define some extra authorization parameters. The first thing we want to do is define that we're using a response type code and this is basically confirming the authorization flow type that we're using it's called the code grant type. We want to also specify that we need an access token that can be used for a specific audience in this case the audience that we want our web application on port 3000 to be able to talk to is the API on port 5000. And finally we're going to find some scope information so we know that we want to start an open ID connect based authentication process that's going to follow the open ID standards. We want to get profile information back and if it's available also the email address. So we'll save this we do need to find the client secret so we'll jump into the end file of here I'll add it just under the client ID and we'll jump back into the ulterior dashboard real quick and go over to the settings tab in fact no we need to go to the applications because we're getting client secret for the express app configuration so we'll jump in here and under the settings tab we've got our client ID here which is in the environment file already and now we'll just copy this client secret and we'll paste that in here and hit save. Now even though I said before running nodemon which means that when most file changes are detected it'll restart the web application for us the dot end file is not one that's normally checked by nodemon so I'm just going to come down here and manually restart npm we can see that we're happily running on port 3000 again never come over onto the right hand side here and refresh we see that it's starting to spin out we're not actually getting any information the reason for this is that we don't actually have the access token yet we need to log out and log back in first in order for the new configuration that we defined in our application to send a message to Auth0 and get that access token one other thing we need to do first though is to tell Auth0 to allow our application to talk to the API so to do that we come down onto the API section here again and edit the settings for the express API configuration we we configured just earlier and we need to go over to the machine to machine applications and in here we'll see a list of all the applications and the applications tab we can see that the express app that we've been working with is not authorized to generate access tokens for this API so we'll just tick that so that now when we log into the express app again it's going to generate that access token we'll switch back over here and we'll click on login and this time when we log in we're going to get this extra authorization request it's basically saying do you allow the express app to receive access tokens and send information for the express API we want the profile information and yes in this case we do so now we're logged in again and if we go over to the secure page we can see that the request to the private endpoint whereas before it was failing and just showing us the default empty object is now getting that information back from the API with the type private so that's it in a nutshell we've managed to take an express app that already had a little bit of authentication inside it we secured one of the web pages so you had to be logged in to even render and we've created a simple API that has both public and private endpoints where the private ones need an access token in order to authenticate which is provided by Auth0 or any open id compliant provider to the application during the login process i hope this has been helpful i'd love to get your questions out in the comments below if you're trying anything like this let us know what you're working on i'd love to find out more if you have found it useful please click that like button it does help other people find out about the video too and we're always releasing new content on the Auth0 channel so hit that subscribe button bell notification will give you earlier notifications of when new content comes out and until next time happy coding