 Good morning everybody. Thank you for joining. I'm Aaron Precky and looking forward to today and talk about how to build a secure website from scratch. A couple of logistics. We've got. An hour here today and we're going to be covering some. Some topics and slides and then I'm going to do a demo of actually building writing some code live as well. I'm happy to take questions during the session. I can't promise I can get to all of them, but I'm happy to do that. If you do have a question, make sure to use the Q&A box in this interface. I won't be paying attention to the chat, although that might even be disabled so that makes that easy, but do use the Q&A box here and that makes sure that gives me an easier way to keep track of the questions and answer them. With that out of the way, let's get started. I'm Aaron Precky and I've been involved in OAuth Group for a while now working on the actual OAuth specs and that is of course probably the industry standard for getting, for doing login on websites now. And we're going to talk about what OAuth is and why it's better than just using a password for example. I also maintain the website OAuth.net so if you do have any questions about things as we're going, this is a great place to look them up and I try to make sure that's up to date and a good resource for finding other blog posts or videos about the different concepts that we're going to be talking about today. So that is a fantastic resource. So we're going to start with a little bit about what OAuth is and why it matters because this is kind of the foundation of building a login page into a website these days. This is the spec, the OAuth spec and if you ever tried to read this I apologize because it turns out specs are actually terrible at being tutorials. They're not really meant to be that. They're more like a legal contract that you would read after you're already familiar with the landscape. So not the best way to learn it and the worst part about OAuth is that it's not even just one spec. It's actually a whole bunch of specs put together and there's a couple of reasons for this. Some are good, some are bad and that's just the way it is and I completely recognize that it's a little bit overwhelming to try to figure out how to go through that. So we're not going to go through the specs in order because it would be very boring and it wouldn't make a lot of sense. So instead we're going to talk about why we even have OAuth in the first place. Starting with a little bit of background on what we had before OAuth. So before OAuth it was actually very common for third party apps to request your login to providers like Google or if an app like Yelp wanted to get access to your address book that lives in Google it would ask you for your Google password. We understand now that this is like a terrible idea. We would never go around typing our Gmail account login into random apps like Yelp or Facebook but it was very common at the time because there wasn't much of an alternative and this is really what drove the creation and adoption of OAuth which was users do want to give access to their contacts to Yelp because of whatever Yelp is promising them. However giving up their password means that that app can then do anything on their account and access all of their data. So we're looking for a way to let applications access one part of the account while not having to be able to access other parts of the account and this was the original sort of problem statement that OAuth sent out the saw which was how do we let apps access data without giving the app the password. And this holds true even for first party apps. It doesn't have to be a third party app issue. It was originally developed for third party apps where you could have an app by this brand accessing data from this other brand, Yelp trying to access data from Google or Last if I'm trying to access data from Spotify or Buffer trying to post tweets for you and that's all fine but it turns out it's also useful for first party apps as well for a couple of reasons that we're going to look into in a second. So this is really what drove OAuth and as all these companies were starting to build out at the same time they realized they all had the same problem. So they started working together and actually wrote down a standardized way of doing it which is what we now know as OAuth. So now you go to Yelp and you don't see a give me your Gmail password it's all these buttons like log in with Google, log in with Facebook and this is actually sort of interesting because again the original goal of OAuth was to get access to data in API so nothing in OAuth actually talks about who the user is it's always about just getting access to an API so I like to think of this analogy of checking into a hotel where you go to the hotel you go to the front desk and you show that person your ID and credit card they give you back this hotel key. You take the hotel key and you walk up to your room you swipe the key on the door and the door opens up and lets you in. This is actually exactly analogous to OAuth because the person at the front desk is the authorization server the one responsible for guarding access to the keys handing them out checking IDs things like that. That key card is an access token and it gives you access to one or more APIs like the room of your hotel or the pool or the gym or whatever it is. And this has a couple of really important properties which are also the same in OAuth which is that if you are using this hotel key you don't actually care what's on that hotel key in order to use it you just care that the door knows what's on the hotel key. So you don't actually need to be able to read it you just need to be able to approach the door and use it. And that's exactly the same as with OAuth. OAuth access tokens do not get interpreted or read by the application that's using them. They get read by the API instead. So if you do want to know about the user you need something besides OAuth because OAuth doesn't give that to you. And that's where OpenID Connect comes into play. So OpenID Connect takes OAuth as a base as a foundation and then adds in the user identity information on top of it. So we're going to start by talking about how OAuth works and eventually get into OpenID Connect and then see how to get data about the user. OAuth spec is based on this idea of the goal is to get an access token. And once the app has the access token it can go and access an API. Eventually we're going to get to learning about the user. But how it gets the access token actually depends on a lot of factors like where the app is running, what kind of app it is, what the environment is running in. And there's a lot of options that the OAuth framework gives us for these kinds of applications. Turns out the primary one is the authorization code flow, which is the one that we're going to talk about today because it is the most common and it's the most useful in the most different environments. It's useful for traditional web apps that are running on server. It's also useful for mobile apps. It's useful for single page apps. And you could even use it with command line apps. It's a little bit weird, but you could. Then there's also the device flow which we're not going to cover today. But that is for devices that don't have a browser in them, like an Apple TV for example. There's also the client credentials grant which is for when there's no user present. It's just machine to machine. And there's a couple of deprecated flows as well which is because of some security concerns with them and the environment they were created in is a lot different now. So we'll talk a little bit about those, but we're going to focus on the recommendation of the authorization code flow with Pixie. The point though is that at the end of all of these flows, the result is that the app has an access token and it can now go and use the access token to make an API request. Regardless of which flow was used, it doesn't matter after the access token is issued. To that end, we are going to take a look at sort of step zero which is client registration. If we're going to build an app, if we're going to build a website and then secure it with OAuth, we need that website to have its own identity within the system, within the OAuth system. For this demo, I'm going to actually use an octave developer account which I have created ahead of time. So I'm going to switch to show you my computer screen. What I've got here is I've got an octave developer account from developer.octa.com and this is a free account and it has a lot of the features enabled that you don't get on the other octave accounts. So this is a great way to try this stuff out. It gives you a OAuth server on your account. Step zero is client registration which is the idea that this application that we're going to build really needs to have its own entry in octa, in whatever your OAuth server is. So I'm going to go here, click add application. We're going to build a web app because we're going to write this code which will eventually be running the server side and we're going to call it auth code demo and for this demonstration, we're actually going to write this application as like a one file application which is just to demonstrate how little code actually is required in order to do this. So I'm going to send the redirect URL just to the same homepage of the app because I'm only going to be creating one file. Registering that will give the app a client ID and a client secret. Now I get a client secret because I chose the option of a web server app. So here I've now registered the app. This app now has its own identity system which means it has things like different, you can associate different permissions or settings within this application and now we are able to go ahead and start one of the OAuth flows. So the client ID identifies the app. The client secret is effectively the app's password and it's really important to treat that the same way you would treat a password as in don't check it into your source code the app needs to protect it. We're going to have to keep that in mind. The other thing about the client secret is that some applications can't use client secrets and that's because they don't have a way to protect it. So for example what we chose when we created that app in Okta was the web server app and that's known as a confidential client in OAuth terms. So in OAuth terms a confidential client is one that can hold on to a client secret and keep it secure. The opposite is a public client which does not have the ability to keep strings secret and examples of those would be things like mobile apps and JavaScript apps. Now this is a tricky one because JavaScript apps, if it's an entirely connected app like single page app running in a browser, there's no server back end. Whatever you put into your source code of the JavaScript app is delivered to users in their browser which means if you were to try to put an API key or something in there it wouldn't be secret anymore because anybody could just go and view source and start poking around and seeing whatever you put into the source code. So you can't use a client secret in a JavaScript app and mobile it's a little bit harder but there's plenty of tools available to decompile the binary file that you get from the app store and start poking around and looking at the contents of the binary file. So again you can't use a client secret in a mobile app. Now what's the client secret good for if we can't use it in a mobile app? Well it's really just like an extra layer of security within the whole system and as we'll see it's not actually needed in order to successfully get an access token. So we're going to start with we're going to start with by talking about the recommended flow which is authorization code flow and pixie and then we're going to do a little demo of actually writing this code to protect this website which I'm going to then you know we're going to create this website from scratching one file. So authorization code flow plus pixie. This is the recommended way to get an access token for an application to get an access token and also eventually the user's identity information about who just logged in. Pixie was actually developed a while ago specifically for mobile apps but it turns out that it's got a bunch of useful properties that make it also useful for every application so it's just the recommendation now. Let's take a look at how this works step by step before we actually dive into the specifics of actually using the actually looking at this on the wire and then eventually writing the code. So up at the top we've got our sort of the players involved in this exchange and we start off with the user is using like a phone for example it doesn't have to be a phone it could be their computer browser accessing the application and that application might be an app running on the phone or it could be an application running up on a web server that they're accessing from a browser. It doesn't matter where it's running it still is considered to be the application in the OAuth sense. The OAuth server is the one that's going to be issuing access tokens. Now if you're using Okta, Okta is playing this role of the OAuth server and you don't have to worry about how it creates access tokens or how it handles validating user logins or anything because all you care about is the other end of it which is either pretending an API or a website. This API is where we're going to eventually send the OAuth access token to be able to go and access data behind that API. So let's start the flow with the user is looking at the app or launching the app or going to the app's website and clicks the button that says log in. The app is going to say okay, hang on, I'm going to generate a new secret right now, random string and I'm going to hash the secret. So a hash is a one way operation and a very simple hashing algorithm might be some. So if I told you to pick 10 random numbers between 100 add them all together and tell me the answer, I would not be able to tell you what 10 numbers you chose. So that's not a very good hashing algorithm because eventually I could figure it out or at least make a couple of guesses but that's the idea. So in reality we use a much better hashing algorithm but it's the idea where even if someone has the hashed value they can't actually know what the original value was that made that hash. So we've got the app holds on to the secret, calculates a hash and then gives that hash value back to the user to say hey, go over to the OOS server. I don't want your password. I don't want to deal with trying to figure out how to validate passwords. The nice thing about avoiding about the application not needing to ever touch passwords is now you never have to worry about whether the application is actually properly protecting passwords. So the app never actually touches it. So the app says, all right, go over to the OOS server redirects them in a browser to the OOS server with that hash value. So the user is now approaching the OOS server saying, all right, I'm trying to log into this app. Here's this hash value it gave me. Here's also my client ID that was part of that first registration step. The OOS server says, cool, who are you? This is where the user logs in. Their password lives in the OOS server so the OOS server is where they're going to be entering their password to confirm their identity. After they approve that request and log in, the OOS server says, great, take this temporary code back over to the app. So the user takes that temporary code, delivers it, brings it back to the app by visiting the app's website again and says, all right, I got this from the OOS server. You can use this to get an access token. Now the app can say, all right, here's the coding off from the user. Here's that original value that plain text I used to generate the hash, please give me an access token. The OOS server is able to take that original value, calculate the hash, compare the two hashes from the first step and the last step, and issue the access token. And now the app has an access token or as we will later see also an ID token to get data about the user and they can, they're now logged in. So there's two different color lines here, right? This is the difference between the front channel and the back channel. And this is a really important concept around why this stuff works this way and why this is secure. So the whole first half of the exchange is, the blue lines are front channel requests. The idea with the front channel is that it's actually using the address bar of the user's browser to move data from between two machines. We've actually got data moving around between the OOS server and the app which are pieces of software, but we're using the user's address bar to move data around between those two. That's the sort of weird one. The normal one is the back channel request, which is like an HTTP request from a client to a server, which we're all very used to and we kind of take it for granted. There's a lot of benefits to the back channel that we sometimes just forget about, which is that by using the back channel, the application actually knows it's talking to the right server because it's making an HTTPS request it's secure, it's encrypted, and the response comes back in the same connection. That's all great. I like to think of that as hand delivering a message where you can walk up to somebody and give them a thing. You can see who they are. They can see who you are. You can see that they took it. You can see that nobody else is coming along and, you know, stealing it away from you as you are doing the handoff. Sending data over the front channel is more like throwing it over a wall where you can't actually see it over the wall to see if they actually caught it. This is really important. Anytime you send or receive data from the front channel, you're missing some visibility into the exchange. From the sending point of view, you can never really be sure that it got there. You might be like pretty sure but you can never actually be sure. On the receiving end you can't actually see where it came from. All you know is that something appeared over the wall and hopefully it's from the place you thought it was, but it could have been somebody else throwing something over the wall at you instead. There's just no visibility, so we never are actually sure. You might be wondering why do we use the front channel at all? The reason is because this is how we actually ensure that the user is at their computer and was actually there and did actually log in and that it isn't the app just taking the password from someone and saying, oh yeah, no, totally the user said it was okay. We want the OAuth server to be sure that the user did approve this request and was in front of the computer. It also means that the thing receiving data doesn't need a public IP address like a mobile phone or a single page app doesn't actually have a public IP address that a remote server could push data into. This is a great way around that problem as well. That's the summary. Let's now walk through this step by step and then we're going to go actually write code to do this. Step one, the app generates that random string. This is called a code verifier. I don't like the name. I always get the two mixed up. It's code verifier and code challenge, but it generates a random string. This is the secret or the one time use secret. It has to be a certain length, certain characters. Then the app calculates the hash which is a shot 256 hash of that first string. This is now a, it's always going to turn out to be this length. It's then basically for URL encoded because we're going to put it into a URL. Then the app goes and builds the link to send the user off to the OAuth server. This is an authorization code request and there's a couple of parameters in here that are telling the OAuth server what to do. For example, response type code means we're doing the OAuth code flow. Client ID is that, again, that public identifier of the app so the OAuth server knows which app they're trying to log into. That redirect URL is where the app is waiting to be returned, to have the user return to. Scope is what the app is trying to access. This again depends on what APIs you need to access, but we could say, for example, that this app is trying to access your photos in an API. State is a random string that the app just makes up. Also, although it could also be indicating where in your app you want to send the user back to, whether it's the home page or a dashboard or the checkout page or whatever it is. Then code challenge and code method. These are the pixie parameters. This is that hash and then code challenge method is saying which hashing algorithm we use. This turns into a link that says log in. The user is going to click this and then get taken to the OAuth server. It might be the Google OAuth server or the Octa OAuth server. That is where they're going to log in and eventually the OAuth server redirects them back to the application. When it redirects them back, it's either going to give an error string if something went wrong or generate an authorization code. Now the app is able to make a back channel request to exchange that authorization code for an access to it. It's going to make a post request back to the OAuth server saying, here's what I'm doing. I'm using an authorization code. Here is the code. Here's the redirect URL. Here's a client ID and then also the plain text version pre-hash that the OAuth server is going to then hash. For public clients, if it's a mobile app or a single page app, there is no client secret used in this request at all. If you are writing a web server based app, then you would include the client secret. Then you get back an access token and the app can consider the user logged in now. Let's go ahead and actually do that now using this application and some sample code that I've got ready. I've registered the app already and now I have a client ID and a client secret. We need to start by let me load up this code. It's not even boilerplate. It's just a little bit of placeholder functions that make this a little bit easier to do. I'm going to write this app in one file and we're doing that just to demonstrate that it doesn't take a lot of code to do it. You would obviously probably use a framework or something to do this but we're trying to show what's actually going on under the hook. I've just got a PHP file here and if I don't do anything first, then the user is going to be logged in and see the dashboard. If I take out these to check if the user is logged in and visit this, it says we're logged in. We don't know who the user is obviously so we're not actually logged in but this is now not protected. This would be the dashboard. This would be the dashboard of the app. This is what we're trying to protect. We don't want this to be visible when the user is not actually logged in. Let's go ahead and add authentication to this. First, eventually we're going to store the user's username in the session and that's how we're going to consider them logged in. Session is like every web framework has this. This is just PHP's version of this. You run session start at the beginning then you get this variable to be able to store things in it and then when the user reloads the page, they're still there. Which is like magic. 20 years ago when we were all first learning PHP on the web but this is sort of the basis of web these days. Every framework has something similar to this. You would use whatever is the most appropriate for your language. Now because we're looking for a variable in the session I'm now not logged in. We've now protected this with a check to see if the user has a session with a username in it and now we have to fill that in somehow. What we're going to do is use an OAuth flow to first get an access token and then eventually get an ID token which we're going to talk about in a second. I have a little bit of a few variables here which is sort of like in line config and we're going to fill these in. We need the client ID. This is a PHP app so I have a client secret as well. It's running on localhost 8080 so that's the redirect URL. Now we need to actually know where we're going to send the user to to go log in because this application we don't want to put a password prompt in this app because that would not be secure and we don't want to be collecting passwords from users. We want to talk to the deal with passwords. We need to figure out where can we send users to to go log in. It turns out that this issue URL is sort of a magic string. This issue URL is if you add on this dot well known thing onto that URL you actually get a URL that contains a bunch of useful information. So we've got things like the authorization endpoint and token endpoint which are the two URLs we need in order to be able to do that exchange. There's other things in here as well which don't really matter for now so we're not really going to worry about those. So I could just copy and paste this as the URL but because this is actually a JSON document we can fetch this in code making it a little bit easier to configure. So if I drop that issue URL into my code and then add on the dot well known path and then fetch it story and metadata now I can do things like authorization endpoint and it will grab that string from up here. So cool. All right. Now we've got a our config and we're ready to start in no off flow. So if I scroll down we're going to we've got this little debug thing here right if octa returns us back returns back to this app with error in the query string we're going to show the error message right so like if something goes wrong we're going to end up back at the redirect URL with error equals blah blah blah and then we're just going to show it on the page so we can see what happened. Here is where we're waiting for the return with a authorization code and eventually octa is going to return us back with code is something and we're going to do we're going to have to go exchange that for an access if that's not set then we skip all this for now here around here now so we need to actually now build up a link to send the user to go log in to octa so I mentioned that there's that state parameter it's just going to be a random string that we're going to generate I also need to now make the pixie code store the pixie code verifier the plain text locally in this app and then generate a hash of it and send that in the URL so to do that we're going to say code verifier is let's just copy this and make it a little bit longer okay and then code challenge is the basic c4 URL encoded version of hash of the code verifier and I think I did that right here's the authorization endpoint we're going to add a bunch of query strings parameters into this URL so we need to tell the OS server what we're doing response type is code we need to tell who we are so client ID it's this app that is wanting to log a user in where is the app running redirect your right okay we need to give it a state is there and we need to give it a scope of something for now let's just say that it's contacts so I can get through this part of the demo and then we need to add in the code challenge so code challenge and code challenge method which hash we are using cool okay now we're going to build that into a URL put it in this link that says login so if I go back to the homepage now we see the link that says login if I look at the source code then we see we've got authorization endpoint response type code client ID redirect your right state and if I refresh then the code challenge and the state change every time right cool so here we are I visited us in a logged out window then I'm not logged into octa in my incognito window and if I click login I get taken to octa of course and then octa asks me to log in so I'm going to go ahead and do that when I click sign in this is actually a feature of I've gotten able on my account the consent feature which you really only need to do for third party apps it's not really necessary for first party apps if I click allow I will get redirected back to local host 8080 and now look there's a code in the query string also there's that state value so now we're ready to go and finish this off so back up to here if there is a code in the query string which there is now first I'm going to check to see if the session state matches that state otherwise something is going to go something will be wrong right like like I just take this and put it into the other browser because that means somebody is trying to do something sneaky okay then we go talk to the token endpoint and exchange that code for an access token this is that poster that type is authorization code we include the code we got from the query string which is in there we've got client ID now this is again a server-side app I am going to use my client secret and we've also got redirect URI and let's see what happens is this enough I know refresh is required because it turns out it's actually very short-lived the only last I don't know exactly how long it is but it's like definitely less than a minute I'm already logged in so octa did not prompt me again I got returned back there's a new code new state and now I got an error from octa saying oh pixie code verifier is required because I used a code challenge at the beginning so I can also send code verifier which is in the session probably expired yet start over to get a new one and cool now we got an access token back so at this point we don't actually know who the user is we just know that there is a user because the access token does not tell us anything about the user you might be saying but oh but this is a jason web token and technically yes it is but as far as the app is concerned it's not it does not matter whether it's jason web token because the application does not need to should never actually try to learn anything about this access token just like a hotel key card when you go to a hotel you get that key card you don't go and use a magstripe breeder to read the data on the card you just go to your door and the door deals with it if you did try to read the data on the card you might learn some interesting information or you might not it doesn't matter because all you care about is does it open the door okay so we now we can't really like we don't know who the user is so we have to do something else and we have to learn the user data some other way there is actually an API met API in octa to look up user information which should be one of the endpoints here but instead what we're going to do is we are going to use open any connect to go and actually learn about the user that way so let's talk a little bit about open any connect before we get back to the code so like we saw the access token doesn't actually tell us who logged in the access token just tells us that someone logged in and that we could now make API requests to this imaginary API that we haven't made yet open any connect is about identifying users so again OAuth accessing APIs open any connect who is the user identification and open any connect is not a whole new thing it's actually built on top of OAuth so all the the code we just wrote is actually almost already open any connect because we only to add a tiny bit of code in order to make it an open any connect request so what exactly does open any open any connect add the primary thing is adding is a new kind of token we saw that access token which as an application we're never going to worry about what it is we're just going to send it to an API the ID token is meant to be read by this application this is how we learn about the user so if your OAuth server uses json web tokens as access tokens which octa does then these tokens actually look very similar at a first glance however it's very important to not use them interchangeably because they are not the same and they have slightly different information in them and the security properties of them and the model that's based on assumes that they are not the same kind of thing so these tokens are intended for different audiences which is the sort of spec terms for it the access tokens audience is the API the resource server the ID tokens audience is the application so that's who it's going to be read by so let's dive into json web tokens really quick json web token is a three part token used to encode and sign json data the header that talks about what the structure of the token is and how it's signed the middle part actually contains the data you care about and the bottom part is the signature which is how you can check whether it's valid which is actually only necessary in some cases as we'll find out so this might look like it's unreadable you know nonsense but it turns out that it's actually not encrypted at all so if you take this and copy and paste it and paste it into a base 64 decoder you'll see that it's actually just json data so this is again a really important thing to keep in mind which is that the whatever data is inside this token the ID token for sure and if your access tokens are json web tokens then also your access tokens that whatever you put into those tokens is visible to users and developers of these apps so just keep that in mind as you're designing what you put in these tokens okay to get an ID token we're going to do the same flow we just did we're just going to add a new scope to that request because that's all you have to do to turn on open ID connect you turn on open ID connect by adding the scope open ID there's a couple others defined as well like profile email address phone to get other parts of the user's profile information probably all we care about is the name well we could also get their email address as well so the user clicks this link again this is like the same thing as before we're just going to add in scope they're going to get sent to the OAuth server login they get redirected back with this temporary code which we then exchange for an ID token which will come back along with the access token and this is a really interesting difference as well which is that by doing it this way it actually doesn't matter that this ID token is a JSON web token and we don't care about the signature anymore all we have to do is just treat it like a weirdly encoded bit of JSON data because we don't care about the signature because we actually know where we got it from already we got it over the back channel we know it came from the open ID connect server we know that it's not been tampered with in transit because it's over SSL we know that it was intended we know it's the right ID token because we got it in that responsive request we started now if you got this over the front channel that would be a different story but we're going to do this over the back channel because it's a lot easier and it's just faster so again the ID token is a JSON web token so if you decode it you'll see a bunch of these claims in it if you do get it over the front channel which means that you use a different response type so if you use a response type ID token for example you get an ID token back in the redirect which is like it's flying over the wall and you don't actually know where it came from so if you don't know where it came from you have to verify it and that's what the JSON web token is for that's what the public key signing is for and you're going to use a library to do that because it's too much code to write by hand which is also why I don't like doing it also it's just more work so you have to validate all these claims because just because you got this ID token doesn't mean it's actually for your app if it came over the front channel you have to treat it like it's untrusted data you have to treat it like it's an attack and verify it and only then only then actually so this is why I like the authorization code flow with OpenID Connect because it's so much less code which we're going to see in a second there's another important attack that it prevents if you use Pixie so it's just overall a very good idea to do it that way so we're going to start back to my code we're going to take this app and now turn it into an OpenID Connect app so again all I have to do is add in a scope let's just switch to just OpenID and see what happens that's all I'm going to change and I'm already logged into Octa here so when I click log in I'm going to get redirected back immediately now I got redirected back and look there's a new token and I mentioned that there looks the same starts with the same few letters there's a dot around there it's about the same length because they are both JSON web tokens but we're going to ignore this one and we're going to only use the ID token this is how we're going to find out information about the user so if I take this middle chunk again I don't care that it's a JSON web token right now because we got it over the back channel so if I just take this chunk you can see within it there's a lot of stuff here that we don't care about it's only important in the front channel but this is the main one this is the thing that identifies the user so subject subject is short for subject which is essentially the unique user ID for this user account it is not a username and it's not an email address it's not meant to be human readable it is guaranteed to be unique and stable for this user so even if the user changes their email this stays the same this is the one you want to use to say like this is who logged in so we don't really know we don't know anything else about the user we just know that someone with the subject logged in so at this point we could actually now write code that does that so we're going to go back to our response we're going to use that authorization code to get the access token here which is what we see printed out right this is what we've printed out here access token response we're going to now continue and say if there is an ID token in the response to this then we're going to now do this this is why again I think it's a little bit silly that it's wrapped up this way but we're going to take this string we're going to split it on the dots right we're going to grab the middle part which is this we're going to then base 64 decode that which gets us this we're going to then Jason decode that so we can actually access these values in code and now we're going to use them so let's say actually subject is user info sub which is the sort of most appropriate way to to make sure that we are actually is logged in so this way if we were to like create a record in the database for example we want to make sure that this sub is the key by user that way when they come back even if the email is different they get back to the same user account so okay we're going to store that and then we don't know who they are yet so we're just going to say hello and show their subject then back up at the top we're going to change this to say if there is a subject in the session then they are logged in so start over again we get redirected back it found the subject out of that base 64 encoded jason string and now when we go home we got the dashboard and we are logged in as this user so now this is you know not something you actually want to show to a user we want to know who they are so we can put their name on this page instead so to do that we're going to add a new scope which is profile and while we're at it we'll just also add email log out and log back in and now if we take a look at this middle chunk and basically for decode it some actually useful information we got the user's name and their email it should only be used to actually like contact them you don't want to store this as the user ID in your database because they might change it and somebody else's account later always use the subject as the user identifier but we can now greet them so we can go back up here and say where we extracted this up we're going to also now put the name their name in the session and we can also put the email in the session and now up here in our dashboard we can say logged in as show their name here log out I can get a new ID token store everything in the session I've got to change it there but if I go back to the dashboard it now shows the user's name cool so that is how we actually now have protected this dashboard you know of course in your real application like this is going to be a whole the whole application there but this code now only runs if there is a user who logged in through your octa org and nobody else can actually visit this link now and see this dashboard so we take a look at the questions real quick the the access token this is a the access token we haven't really used here because we were protecting this website this application by using the ID token to figure out who logged in and we now only know we we only get an ID token if it's a valid user in the octa org which we can now manage the the users over an octa and that's where we can you can see I've got a couple other user accounts up here that is where we can decide who gets access to this application right the access token isn't really useful for this app because all the data lives in this app if this app needed to access an API that's what the access token would be for so um we can I can walk through this code which I wrote yesterday um this is probably more than we actually care about but let's yeah let's do that so let's pretend that we're building an API and um the API that we're going to build is going to show us a list of photos that belong to this user now the important thing to remember here is that this API is going to be on a totally separate server from the application I mean that's generally the architecture that you've got you've got APIs on the back end you've got the application which might be a single page app um you might have a application that's a mobile app and that's going to be on in the user's hands accessing a remote API so this is the remote remote API now the application we're going to mimic the application by uh just using a command the command line and we're going to do that by sending a request to the API which uh I should technically be running this on a separate port but that's too much work right now um we're going to send the access token in a header authorization and then we're going to go grab the access token from um we're going to grab a new access token because I didn't save them from before grab this access token and put it there and see what happens so we get this API um we actually make an API request without the token and what we did was if there is no access token this API is going to grab a list of files in that photos folder and show only the ones that are in there which are public photos and you can see that list of file names matches right okay we're going to only show the ones in the secret folder if there's a valid access token so if there's no access token set we just return the public photos if there is an access token set we can actually validate the access token now there's more than one way to do this the easiest and least amount of code way to do it but probably the worst way is to every on every API request go and fetch um request from the authorization from the introspection endpoint back to octa asking if the token is valid so we send the access token over to octa to check if it's valid and if it is we will get back uh response active is true so if I send this with an invalid token then octa says it's not valid and we return back invalid token so we're able to now protect this API using an access token if I send a valid one we should now see something which is I think I probably just copied that wrong um it looks right I bet my client ID and secret are wrong because I delete that application so I have to add a new application for the API which is uh here a new client ID and client secret for that API to be able to check tokens and when I do this try the request again okay so it says something different now which is unauthorized why does it say that? well because I actually want to protect this API and only let applications access the API if the access token includes the scope photos I'm going to go back to my app, add the scope photos into the request go get a new access token now we've got a prompt right wants access to my photos let's go grab the access token and use this in the request and now we've got the secret photo which is the API code now if there forget about this, get rid of that that's distracting we check the list of scopes in the token if there is no photo scope we error out if there is we now also grab the secret photos and return those in the result as well so now we're able to run different code on the API you could also just say like if there is no access token you could just say unauthorized unauthorized here and now it's a private API that has no public you have to have an access token to access it so that's the easy way there's more better ways to do this which are I will save for a separate session there's also a lot of videos on our YouTube that go over this stuff as well let me take a look at the questions real quick and then wrap up so here's a question about how to protect a token based REST API method if we pass the token free to request it will show in the browser console and middleman can misuse the token this is a valid concern if you're running a single page app it's running in a browser and that is where the access token lives and is being used from then there is always a risk that something could extract that token whether that's a different browser extension on your machine or the user doing it intentionally it's not going to do it themselves or anything like that the number of ways to actually extract that there are some and they are worth concerning yourself with it's mainly around cross-site scripting attacks so like every JavaScript that you embed on your page has access to that page so like your analytics, your ad trackers all that could be extracting these tokens and you would ever know that is a valid concern however it is not necessarily so much of a concern that it's not worth doing it this way so if you are if it is a concern and you are not willing to have any of that risk at all then the best way to do it is to not have access tokens in the browser and use HTTP cookies instead where your access token lives up on a server that back in that supports the single page app so that's the sort of more secure architecture in that model the but yeah like I said it's not always a concern because if you audited your code and you know exactly what scripts are there and you've made sure there's no cross-site scripting attacks possible on your app then you can deal with access tokens in the browser because you've reduced the number of ways that they could be extracted I will make sure to send the sample code out so a few people asking about that so what are the expiration dates around access tokens and ID tokens actually the both the ID token and the access token are going to expire so if we have if we look at the access token response here the access token lasts for two hours in this case it's up to the server to decide that but again that's really only the concern of the API so the API is going to go validate the access token and it would be able to check whether the tokens expire it's the ID token that we care about in the application the ID token does have an expiration date as well and again if we look at the basic C4 decoded there's a timestamp of when it expires so yes technically this application should only consider this user to be logged in for this amount of time and you might do that by when you actually set the session cookie for this app setting it to expire at that time or actually storing this ID token client side like in the application and checking it on every request so if you're doing that for example like if I if I only go back to my app what we did here was we extract the data out of the ID token and save that in the session we now don't have the concept of this expiring if instead we actually say ID token and store the whole thing we can actually now check the expiration date we could even just say session expires in at some point right this is now stored server side like on this applications web server so we can now use this checking locally to see if it expires and then if it's now past that timestamp we kick the user out and give them to log in again if you're doing a so there's no traffic back to octa in that case right because this is the ID token intended for the app checking expiration date itself so hopefully that answers that question and I think that's all the time we have we're about at the top of the hour let me quickly just talk about where to go for some more things to read and learn about because this was just scratching the surface of this stuff and there's a lot more to it and a lot more details to learn so OAuth.com is the electronic version of the book that I wrote OAuth 2 Simplified and that is a great place to go for a lot more of these in detail questions there's also the OAuth Playground which is a good walkthrough of the authorization code plus pixie flow like we saw but also all the other flows and you can see how they work and look at the requests that are being made the Octa developer blog is a great resource for tutorials in different languages and frameworks and that's a great place to go to again dive into the details about specific frameworks and languages that you might be using since you probably are not writing your application in one PHP file like I just did we also have a YouTube channel youtube.com I'm actually going to be doing a live stream in an hour there and we do every week a happy hour we talk about answer questions from the audience as well as talk about latest news in the OAuth world so that'll be a fun time as well if you do want to print copy of the book that I wrote they're available here OAuth 2 Simplified.com so thank you everybody for attending I hope you got something out of it even though this was a very quick session but we did manage to throw in some information about API security in there as well so yeah thank you all for joining