OAuth 2.0 using Auth0 | React.js and Node.js

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys welcome back to the fourth episode of this web api design series so in the last video i talked about how modern day web api security is implemented using oauth if you haven't watched that video yet the link is down in the description below go check it out in this video i'm gonna show you how to implement the oauth authorization code flow now i'm not gonna build my own authorization server so i'm gonna use odd0 to do this for me if you've never heard of it it's basically a cloud identity provider that helps you focus on building web applications while they handle the authentication and authorization problems for you odd0 has got a ton of great libraries to help you implement or auth for your application but i won't be using them in this tutorial because they kind of do all the work for you and it's much better to learn the entire flow by setting things up manually so we'll be using the http apis directly to get things going once you learn how things are done manually it becomes that much more easier to use their libraries alright so let's have a look at what we're planning to build today okay so the first thing is we're gonna build an api i'm gonna call it the challenges api now this is a protected api that a user needs an access token to access basically this api has only one endpoint that's supposed to return some challenges data the data itself doesn't really matter but you need to have specific permissions to read data from this api so who's going to consume it well we're going to be building a dashboard a front-end and a back-end to consume this data now the reason we need a front-end and a back-end is because we need both a front channel and a back channel to do the authorization code flow in a secure manner so the dashboard front-end is responsible to get the user to log in and authorize and r0 is going to give us back an authorization code we are going to use that code send it over to the dashboard backend and the dashboard back in is going to use that and exchange it for an access token now if the user has the right permissions when we make a call with the access token to the challenges api the challenges api verifies the token against odd0 and then it also checks for the claims and the scopes and the permissions all of that stuff inside the challenges api if all goes through successfully it's going gonna return back the data and it's gonna send it all the way back to the dashboard and we're gonna display the data in the dashboard so we're gonna do all this today and if you're interested in learning how this is done follow through with me okay so now i'm in the alt0 management dashboard for you to get here all you need to do is go and sign up for odd0 create a free account and you'll get here once you're here make sure you're in the apis tab and when you're in the apis tab go ahead and click create api so what we're doing here is basically creating a registration for our api the challenges api so let's go ahead and call this challenges api this is basically the name that we're going to use for this api it's just metadata this part is slightly more important this is the identifier for your api now it doesn't have to be an actual publicly accessible url you can just type whatever you want in here uh let's call https www.challengesapi.com that's it so this becomes your identifier which you'll need to pass along when you're making requests later on let's leave the signing algorithm as it is let's click create okay so now it's done creating our api for us it's given us a quick start which we'll start using in a bit switch it over to node.js but basically let's jump into the settings tab now in the settings tab you can see that your identifier for this api is set this is basically your audience parameter later on when you want to make requests so over here you have your token settings your token expiration this is a rather large expiration but i'm just going to leave it as it is for this demo go back down and you'll see something called the rbx settings now you want to enable our back settings and add permissions to your access token this is because we want our access tokens to actually contain certain permissions which will set up in a little bit and basically that's it you can click save here and let's jump in to the permission section so this is where you set up the scopes for your api so you can have all kinds of scopes like read write and so on they've given us an example here read appointments now we have challenges so let's call read challenges one as one let's give it a quick read your challenges add it in and let's also add something called write challenges write your challenges all right so now we got two permissions or other scopes that this api can provide and uh in this example we're not actually gonna use the right challenges but i added in just so you can see what it looks like in the access token later on so that's it that's basically all you need to do to actually set up your api in n0 pretty simple right okay so now let's jump back into the quick start and if you go over to the node.js section they've given us some sample code now this code already contains your configurations for this api you can see we've set it up as challenges api and it set it up as the audience for us there's the issuer the algorithm and all of this basically all you need to do is copy this stuff in and we can actually jump into our vs code and get started all right so now i'm in my vs code we've just copied over that quick start guide and let's paste it in so let's have a look at what's actually going on here so we have an express application we have a jwt express package we have a jw ks check that's going to be done we are setting up a port at 8080. yep let's leave it at 8080. so we set up a check and we pass in the uri which is our ambient coder the api that we just set up we're saying the audience is the challenges api yup that's correct and the issuer is ambience so basically this is going to verify that whatever token comes our way can add it in as a middleware and verify that the token is from this issuer and for this audience and has this public secret so that's cool so that's just a jwt verification that works fine for us but if you remember we are actually interested in adding permissions checks as well so let's see how we can add permissions checks in order to do this we need to use a package i'm going to call it god and require and the package is express jwt permissions this makes it very easy to set up permissions and check them as a middleware so this is our authorized endpoint let's quickly change that to challenges as we know that's what it's going to be called and uh let's let's actually change this up we're going to send in some json and let's set up the json so let's just call this challenge one this is the first challenge and say challenge two um this is another challenge so basically i'm not gonna invest time and actually setting up all of this correctly it's just some dummy data so i've set it up let's now use our guard so the way this works is actually the guard is a piece of middleware so let's set it up we actually do god dot check and into the check goes an array it's an array of all the scopes that you want to verify for this particular endpoint now this is a get call to the challenges endpoint so i want to make sure that anyone who accesses this endpoint has the scope read challenges that's exactly what we set up in the api so let's make sure this has to be a string so read challenges there you go it's as simple as that and we are pretty much set up so as you can see i didn't actually install any of these packages because i had kind of pre-set up this application but obviously you want to npm install all of these all right so let's see if our application is ready to run oops seems like we have an error says god.check oh yep okay i think i know what that is this is a function so let's see if that solves the problem all right seems like everything is running fine so we've set up our api it's running it's ready to receive requests now let's move on to setting up the front-end application all right so now we're back in the odd0 management dashboard and we're back in the apis so we already created our api but now we need to set up a front-end application or rather the consuming application to do that go over to your applications and click create application so when you click create applications you have a bunch of options here now you can choose whatever you want based on the kind of application that you're building so this can be a native application like something that's a mobile application or desktop application you could also have a single page web application which is what i'm going to be doing so i'm going to select that you could have regular web applications machine to machine applications so basically machine to machine is like servers or shell scripts and so on um you can have you can pretty much decide whatever you want here what i'm going to do for this example like i said is to select a single page web application it's going to be a simple react application so once i select that it's going to give me a quick start it's basically going to ask me what are you planning to use to build this application i'm going to say react and it gives me a nice guide where you know everything is in there for me it goes through everything that i need to configure and it even talks about the sdk which i talked about at the very beginning of this video so i'm not going to use that because that just simplifies everything and it's a little difficult to get the entire flow when everything is just encapsulated by this odd0 react sdk so i'm not going to use that but you can check this stuff out so i've actually set up my application before so i'm not going to do it again let's go back into applications and i'll show you the values that i've used for the dashboard app so as you can see i've called it dashboard app and it gives me a domain for this which is my ambient coder domain and it's given me a client id and a secret now these two are very important pieces of information that we'll need to use to get access tokens later on moving down you have your application uris now because this is a test application that's running on my local host i've used localhost in pretty much everything so if your application is running through a dns you'd have to enter the correct dns here i don't have to do that because it's a local application but it's important that you understand how these work so the first thing is the loved callback urls basically when you request an authorization code you also have to state what your callback url is so you have to mention what exactly that's going to be and if that's valid then r0 will redirect back to this callback url so make sure that this is exactly the callback url that you're going to set up for your frontend application then you can have your logout url your web origins your loved origins and all of that i'll just set it basically localhost 3000 so what this means is that i'm planning to build my front-end application and i'm going to run it on localhost 3000 that's the entry point to my front end application i'm going to set a callback url so i'm going to have a route in my front end application that's called localhost 3000 forward slash challenges this is where the redirect is going to happen to i'll show you how that's done when we start coding the application so that's basically it that's all you need to do and we are good to get started so let's jump into the code okay so now i'm in my vs code to start coding the dashboard front end so this is a react application that's supposed to be the front end and it's going to have two routes the default route and a challenges route which is going to be the callback route that we just configured in all zero so i've already set up some skeletal code let's have a look at how things are structured in this application so we've got our source folder and in there i've got my index.js to support front-end routing i've got my browser router got my app i have some simple html i have a login button component a logout button component and i've set up my challenges route which again is my callback url endpoint and i have a challenges endpoint so i've not really implemented any of these things let's quickly have a look at what's inside the login button so the login button is very straightforward it's just a button and i have a login function that i have no implementation for which we're gonna start coding right now and the log out button is also the same there's no code in there and we've also got the challenges so the challenges component once again is just a simple html component it has some content so this is the data that we're gonna get from our challenges api and we're gonna put it inside this h5 tag so we have some work to do let's get started so let's start with the login button so the login button requires some data from the application that we just created now the first piece of information is gonna be the domain this is the actual endpoint which holds the authorized endpoint so if you remember we have our domain set up as ambientcoder.us.org00.com this is essentially our domain let's copy that over set it up here that's our domain we also need our audience well our audience is actually our backend api the challenges api that we just coded a while ago so we created an id for that we just need to put that in here which is https www dot challenges api.com then we need a scope well for the challenges endpoint we know that there are two scopes that are created or rather two permissions that we're interested in so for the permissions let's just set it up as read challenges we can also get open id to get an id token and a few other things but the focus here is just permissions so i'm going to ignore all of that and focus only on the read challenges permission so let's set that up next up we need the client id so we set up the client id let's go back into our application copy over our client id there it is so that's that then we have to define the response type so the response type is the flow that you want to use in oauth we want to use the authorization code flow so we're going to say code over here that's it and then one last piece of information which is the redirect uri so the redirect uri is what's going to be called once we get the authorization code what we want to do is actually get the application to redirect to this component so in our app we said we have a challenges route so we want to get things moved to the challenges route this front-end application is going to run on localhost 3000 so our challenges route will be in localhost 3000 as well so set it up localhost 3000 and challenges keep in mind that the redirect uri that you define here has to match exactly what you set up as your loved callback url there you go that's the one so this is the callback url this is all the information that we need to send the request over so let's send the request over let's use fetch to do this so let's set up fetch and we are gonna use https forward slash domain so the domain we just defined up there let's use that and along with the domain we are going to say we want to hit the authorize endpoint now where is this endpoint coming from if i go back into the application dashboard and i go all the way down and say show advanced settings and when you go to endpoints you can see under oauth a few endpoints are defined here so this is our authorized endpoint this is where you send over your request in exchange for an authorization code under the authorization code flow so this is where we're sending the request to now along with that we have to pass all this information as query parameters so let's do that all right so one more thing we need to do because this is a front-end route we need to say that the redirect should be done manually this is an option with the fetch request that we can define and once we do that basically what happens is the redirect is not going to be automatically done the problem with the redirect being automatically done is that the browser is going to make a request to this endpoint now this endpoint does not actually exist as a back-end server so this is going to be a 404 what we want to do is reroute it in the front-end application so we can get the response and we can reroute it ourselves by setting it to manual the way we do it is by going to window location and setting it as replace and we can get the response and take the url now when it hits this url which is our challenges endpoint it's actually going to contain the authorization code so it's going to look something like this where it's going to be your code over there so we need to pull out that code from the url in the challenges component so let's go and set up the challenges component right now okay so in the challenges component we know we're gonna have to extract something from the url so the way we do this is by accepting the location and then we want to pull out from the location a query parameter called code so to pull out query parameters we need to get query string so query string from query string you go this is an npm package that we can use and we will use that extract the code pass the location search and that should give us the code so that's that now what do we do with this code so basically we have to call our dashboard backend with this code because that's the service that's responsible for doing the exchange so the front-end has kind of done its job it's got the user to log in it's gotten the authorization code now let's take the code and hand it over so let's implement that piece of code so to do that let's first get use date because we want to get a response back from the api and we want to set it up in state and also we want to run it as an effect so let's get those two and inside we can say constant challenge data let's call it challenges data and say set challenges data and say use date and say let's say none to begin with right so now let's do our use effect so that we can make a fetch call to the back end so fetch and our back-end server is basically gonna be http localhost 3001 now it can be anything but i want to keep it as close to our front end server so it's just one port number away so it's 3001 keep in mind that our challenges api is running on 8080 our front end is on 3000 our back-end for the dashboard is on 3001. now we also want to call it challenges here that's just basically what i want to call it so that it makes it very clear that this endpoint is responsible for doing an exchange and retrieving challenges information from the external challenges api so we do that and we have to pass in the code so say code now let's set up some request configurations so the method you know it's going to be a get we also want pass in some headers and let's say content type is going to be application json and we also want to accept application json that's pretty much all we need to do for the configuration it's not going to be an authenticated call so that's pretty much it now we can start using our response so we got a result this result is gonna be a json so that's a promise we do that and then we do then again and so then we can go challenge data and we can set it as pres well actually it's going to be a json so let's do json.stringify and let's do res so that's going to be good enough for us and one more thing is that we want this to run only if the code changes if it doesn't we don't really want it to run so now we've got the data let's add it in here that's basically all our front end actually needs to do now i didn't implement the log out button so let's quickly do that as well so the log out button is very simple we have a domain which we need again and we also need our client id and we need something called return two so it's return two is where it's gonna come back to and it's gonna be the default this is basically your logout url which we configured as the localhost 3000 so that's all the information we need there and we can use this to make a request to log up so let's do response fetch this is going to be an evade so fetch and then we can call the endpoint which is https and again it's our domain followed by log out and we pass in our client id equals our client id and our return to which equals return tool that we just configured so that's basically it and also again we want the redirect to be manual so we set it up like that and once we have the response we do window dot location dot place and we say response dot url so that's basically how we log out actually so we've kind of set up the entire frontend application the user logs in we send in this information there's nothing sensitive here so it's completely fine to run this in the front end and it sends us a url we route it back in here and in here we have the code which is the authorization code we take that and we send it to our secure channel which is our backend and then from the back end it's responsible to do the exchange get the data send it back over to us once we get the data we set it up as challenges data in our component so if everything goes well we should see things running fine all right so now let's start writing the dashboard back-end code we know the responsibility of this service is very simple it needs to get an access token by exchanging the authorization code with the authorization server and then using that access token we need to make a call to the challenges endpoint which is a protected route the one we wrote at the very beginning so let's see how we can do this to speed things up a little bit i've kind of come up with some skeletal code here it's just some basic error handling and we've already set up a request to the challenges endpoint you can see that there's no authorization header in this request so it's definitely going to fail what we need to do is extract out the authorization code do the exchange and add the access token in here so let's get started okay so in order to do this i want to first set up a middleware that's responsible for getting the request extracting out the query parameters and doing the exchange so let's pull that out of this endpoint and set it up as a middleware so let's say app.use and let's call it pause and obviously this doesn't exist so let's create it and in here let's create a folder let's call it middleware and in there let's create oauth.js so going back in here let's set the reference there you go so that should work now let's start coding what goes inside this middleware the first thing is this middleware needs to make some requests so let's get axios i like to use axios in my backend node applications to make requests so you'd obviously need to install this package in order to use it let's also set up our token endpoint so the token endpoint can be extracted from your application settings in awards mine is going to be this there you go that's my token endpoint so let's set up a function now this is a middleware function so we're gonna get a request object we're gonna get a response and the next callback so set it up it's also not forget to export this there you go so the first thing we need to do is actually extract the query parameter so let's do that by saying request.query code that's what we call it code so let's pick it up and let's also say that if there is no code then we are gonna send a status of 401 and let's say missing authorization code so now that we have it we need to make a request to the token endpoint now let's set up the information that the token endpoint needs from us now we're going to set this up as url search parameters because this is going to be a form that we're going to post over to the token endpoint so let's set it up oops url search parameters and we can do parents.append the first thing we're going to append is the grant type now the ground type is going to be authorization code the second thing is gonna be a client id so client id let's fill this in can go over and get our client id which is all the way up here there you go that's our client id and append we are also going to need our client secret so this is the sensitive information that you really don't want running in your front end let's copy it over just paste it in there as well and we also need to add our code so it's plain and simple code put it in there we also need a redirect uri over here so redirect uri and that's gonna be http forward slash localhost 3000 challenges which is the redirect uri that you set up in the first place so this is good enough let's do axios dot post to the token endpoint and let's pass in the parents then we get our callback so that's our response and what we are going to do with this response is we are going to set it to the request object so that the next piece of the function can actually make use of the response that we are attaching to the request so we go request dot oauth equals response dot data and that's it so anyone else who is along this request chain can actually use the oauth and we're gonna call next and that's it so in case there is an error we are gonna say error and let's let's log this as an error and let's also send a status saying that it's forbidden so let's say reason and let's put in the reason is error dot message change this real quickly so basically what we are saying is we'll make a request to the token endpoint if there is some kind of error then it's most likely a 403 now obviously this isn't what you should be doing there could be different kinds of errors that are coming in but for this example i'm going to assume that it's something to do with authorization so i'm going to return it forbidden and i'm going to put in the actual reason in there so that's it that's kind of what our middleware is supposed to do so now let's start using this middleware in our original endpoint now let's get our access token so it's called access token so let's structure it from the request and we can now use this access token and set it as an authorization header so we have headers and we say authorization and we say bearer and we will give it our access token so let's format this basically that's it so our middleware is going to get us the access token we will attach it to the endpoint the call to our challenges api endpoint and that's going to return some data and we will send it back to the front end if there is some kind of error maybe you don't have the right authorization to access this information if it's a 401 let's send a 401 if it's a 403 your permissions are probably denied you don't have the right permissions so let's send that over maybe something else went wrong so let's indicate that it was an internal server error and this is basically all you need to do to set this up so now we've set up our front-end bit setup of a back-end for the dashboard application we also set up our api i think we're ready to try the entire flow out so let's check out how that's going to work all right so now we're in the dashboard so this is basically what the front end looks like we just have these two buttons that we coded out let's see what happens when i click login all right so login was supposed to make a request to the authorized endpoint the authorized endpoint actually opens up a login page for you so this is done by odd0 for you and you don't have to do anything to set this up so basically i don't have an account here so i'm gonna log in with a signup i'm gonna say ambient coder at gmail.com and i'm gonna give it a password let's give it a simple password all right so now it's saying dashboard app is requesting access to your ambient coder account so let's click accept okay so now we're redirected but we're saying a permission denied error and that's not right or is it well i just logged in as a user right but what i didn't do was assign any permissions to this user so let's go back into our alt0 management dashboard let's look at our users so you can see my user just logged in just a minute ago and if i go into this user and i go into permissions well this user doesn't have any permissions so it actually makes sense why our challenges api refuse to accept this request so let's assign some permissions and let's select challenges api when you select the application you can immediately see the scopes that are available let's give this user read and write challenges permissions click save there you go now let's go back in here let's log out there you go logs me out let's log back in it's gonna ask me to log back in again so i'm just gonna do this one more time so this is pretty interesting so this is the actual consent part where i as the user have to now consent to giving the dashboard application the right to read challenges so once i consent to it it's gonna take me back to challenges with a code now this code is used to make a request to the back end of the dashboard which would have exchanged the token for an access token and sent it to the challenges api that's why you can see the response coming all the way back from the challenges api so let's do one more thing let's get rid of the read challenges one more time let's log out log back in i'm gonna have to type this again there you go permission denied again so just as we expected it so basically that's how you can implement the entire oauth flow all by yourself i hope this example clearly explained to you how the entire thing works so if you go back into this diagram we built the dashboard front end we got the user to log in you saw what a consent granting looks like and then we got odd0 to return back the authorization code send it back to the backend in the backend recorded it to exchange it for an access token and then use that access token to make requests and we saw that we successfully get the access token and send requests but if this access token does not contain the right permissions well then you can't access the challenges api so basically i hope this makes things very clear for you and i hope that this implementation gives you confidence to go out there and build your own applications and start using oauth and that's all i have for you for this video guys i hope you really enjoyed this video i'd love to hear your comments leave them down below and if you enjoy this kind of content please subscribe to my channel so thanks for joining till next time
Info
Channel: Ambient Coder
Views: 7,142
Rating: 4.9250002 out of 5
Keywords: OAuth 2.0, Authorization Code Flow, Auth0, Authentication and Authorization
Id: dyZmsz6usWk
Channel Id: undefined
Length: 43min 52sec (2632 seconds)
Published: Tue Mar 16 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.