 It says we're live. Are we live? Hello. Welcome to our Octadev stream. And today, we've got Matt Rabel and David Neal as well today with us to talk about using tokens in front and end frameworks like JavaScript-based ones. Like, I don't know. I haven't done it in a hot minute. So tell me which frameworks exist that are relevant now, David. Which ones have we got now? What do you mean, like front end frameworks? Yeah, we've got support for Vue and React and Angular. I think those are the official ones, right? Right. Those are the most popular that I've seen. It's interesting because I work on this project called J-Hipster as well. And the one that people are starting to add a new support for it is Svelte. So we don't have support for it in a formal SDK right now. But the big three are the big three. And Svelte, I don't think, has nearly the market share that the others do. Yeah, I think it's interesting or important to point out that the three frameworks that we do support all use the underlying off JS or the JavaScript SDK that we provide. And so they're just syntactic sugar on top of that to provide an experience for those frameworks. So it's not that you can't use any other framework. It's just that we've provided some nice shortcuts that live in those environments. Right, and off JS SDK 4.0 is TypeScript. Really? Now, that's something I can get behind. I actually like TypeScript. I think it's pretty decent. But of course, I am biased because I have lived in the world.net forever. And that was definitely one of the ways that we could use a more strongly typed approach to everything. So yes, OK, so let's talk about why we should care about token validation at all. Is that something that front-end developer should worry about? If you're a full stack dev, how do you think about it? One of you kind of guide me through that. I'll let you go, Matt. All right. Well, I did some investigation yesterday into our off JS SDK because I was curious about it as well. So for me as a developer, I always just assume that if I get an access token back from an authentication process, all I'm supposed to do is really store it and then send it to a back end or some other API to get access to that API. That's how a lot works. And so when this topic came up and I first read about it, I was like, wait, I don't know if you can do access token validation on the front end, right? I don't even know if it's a thing. So rather than looking in the OAuth spec or anything, I just dug into our code and our SDKs. And what I found was in the off JS SDK, there's a validate token method. And if you pass in an access token, it throws an exception. So it's not a thing. You don't do client side access token validation. Now, that doesn't mean you can't. It just means you're wasting your time. If you actually took an access token on base 64 to it and then looked at the JSON and did some sort of validation to make sure it's not expired, there's nothing preventing you from doing that. But it's not going to do you any good because access token isn't any good until you pass it to the back end. So all that really happens on the front end is ID token validation. And those are very similar to access tokens, right? They just actually have user information in them. And you can't send them off to really do anything. Like the only example I've seen where you can do something with the ID token is to log out. Like we have an API where you can send a get request to a log out endpoint. And you pass in the ID token and where you want to come back to. And so that's the only thing I've seen for that. But on the back end, of course, you want to do validation. And so a lot of it depends on how your architecture is set up. And if you actually have control of your front end and your back end, and if you don't, then that's a different story, right? Yeah, so an access token, I guess to kind of back up a little bit, an access token is designed to be opaque to whatever it is that you're creating. An access token is that token that gives you access to a resource. So when you need to be able to get to some data or use an API or access this other service or whatever, the access token is something that, as far as your application is concerned, whether it be front end or even back end, if you're accessing something outside of your application using that token, it's not your job to validate that token if it's any good or not. It's just your key that gives you access to whatever resource that you're going for. And so it's important that you find opaque and that it's just a random set of characters, right? There's no structure. It's just a string. It's just gibberish. As far as we're concerned, as an application developer, an access token is just a string of characters that we should not have to know or care how that is encoded or how to decode that or what information might be in that access token. That is for the owner of that data to worry about. Whereas an ID token can be similar to an access token in how it's created or whatever, it is designed so that there's information in that token that we can access about the identity of the person who is making that call to access our application. Right, and it has to be a JWT, right? That's part of the spec. It can't just be a random set of characters that you decode. Exactly, yeah. There's some core properties that are expected on JWTs or the ID tokens that are part of the spec. And then beyond that, a JWT or an ID token can be expanded or extended to include other information. Yep. So what I heard is that there's kind of like three tokens. That's what I heard there. Am I wrong or is there just two? There's just two, access token and ID tokens. But there can be two different types of access tokens. There can be JOTs or JWTs, and there can be opaque for random string of character tokens. And most identity providers, I believe, use JWTs. And I think opaque support is coming from a lot of them. But typically, with opaque support, you have to do a call to validate versus with a JOT. You don't have to. You can do local validation of that. You're just looking at expired and if the signature matches and all that versus opaque, there's nothing there. So you got to hit an endpoint and say, is this valid? So it can be a little slower. Oh, and refresh tokens. That's a thing from Casey here. Oh, yeah. Let's talk about that, too. So right now, we've got an access token, an ID token. So then we have this refresh token idea. So is there an order to these operations? Is there a specific situation that we would use each one? Do we use all of them? So it's interesting, the refresh tokens cannot actually be used if you're doing a browser-based client. And when I say that, I mean, it can't be used with Octa. Now, I'm not saying it can't be used with other identity providers, because I've used Keycloak, for instance, and if you request a refresh token and a spot from them, they'll give it to you. But Keycloak's very configurable. So maybe it's just something you disable or turn on for whatever. That's a possibility. But I know with Octa, typically, if you want a refresh token, you have to send an offline underscore access scope. And then it'll give you back a refresh token. And if you do that with a spa app, in my experience, it'll throw an error and be like, hey, we don't support this for browser-based apps. So why is that? Do you know the reason? What is the idea behind not using offline access? I think the reason is they don't trust the browsers. Why wouldn't you trust the browser? Because of marketing. You build a website, and you have a nice content security policy that says, hey, only scripts from this website can be used in maybe this jQuery script from a CDN or whatever. You basically have an allow list for those. And all of those scripts will be denied by your content security policy. This is built into web servers. And it's just a HTTP header that gets sent back. And so it's great until you go to production. And then people are like, wait, we want to track our users. And then that's when marketing comes in and is like, hey, can we add this script, add this script, add this script? And after a point, you end up opening up your content security policy. And then if any of those third-party scripts get compromised, well, then they can get access to your local storage, get your access token, and things like that. So I believe Okta has a solution for it in the sense of we can exchange your session ID for a new token. But as far as OAuth, as far as I know, you can actually exchange in the browser a refresh token for a new access token. And so what I've been recommending to people, if they're not using our SDKs, is to basically set up a 60-minute access token lifetime and promptly to log in, because they have to go through the whole flow again. So would you say that most projects that let's pretend that they're just a spot app, that there is no other connected service, that that's all you've got? Should you even worry about token validation at that point? Or just be like, cross your fingers and hope everything's secure? What is the perspective on that? Well, I think the content security policy is one of the most important things, to basically that's your protection against third-party scripts. And so do your best to have a good content security policy. Do your best to use HTTPS at all times. In fact, our OAuth SDKs won't work if you're using HTTP. It'll work on local hosts, but it won't work on any other host. So we have that coded into our actual logic. So you have to be using HTTPS. So you want to force HTTPS for your site. You want to have a good content security policy. And then, yeah, you're storing your tokens. I think we give you a choice between session storage, which means a single tab or local storage, which will allow you to share it between tabs. But that can confuse people because I think we as developers, we like the single sign-on, right? We like to open up a new tab and still be logged in. But there's other people that expect to be able to test multiple apps with multiple tabs. So that's one configuration strategy. The other one we've started hearing more and more about is use service workers. And so you're actually storing access token on a background thread that can be shared between tabs as well. So that's one strategy that I think is a bit more difficult to get at local storage. Because if you get compromised by a third-party script, they can just do local storage get. Yeah, that was my question. Where do you put it in the scope of whatever JavaScript framework you're using? Where do you store that token? Like, David, have you done much with that? That's something I've always left up to the client to do that for me. There are certain methods inside, like the JavaScript SDK that we provide for storing and retrieving the current session and the current tokens. And under the hood, I think it's going into using cookies. But hey, I'm trusting that whatever our SDK is doing, it's the best thing across the options that are available. There's a token manager that's generally used to store the tokens. And I think they switched it recently to use session storage by default. And that was because people wanted only per tab rather than all the tabs kind of thing. And so I think that's how we currently do it. And it's funny because I deal with this a lot on J-Hipster. J-Hipster is a project that generates a spring boot back end. And now we have support for .NET node. So you do it like that as back ends. But the front end, when I first implemented OAuth and OIDC in that, it was like I'd been at oct, I think, a year. And so I was kind of new to all this stuff. And what I found was when I dug into J-Hipster's code, they were doing OAuth in the sense of they were passing in a client ID and a client secret from the JavaScript. And I was like, yeah, I haven't been here that long. But I know that you're not supposed to be having a secret in your JavaScript code. And so what I did after having lots of discussions with the spring security team and other people was we used what a lot of developers are used to. And that is all the validation happens on the server side. All the authentication happens on the server side. So on the client, when you click login, it redirects to the server. The server redirects to the identity provider, whether it's KeyClick or Octa. You log in, you come back, the server establishes a session, and then it just sends back a cookie to the client. And so the client is storing the same thing we've always stored, which is a cookie to talk to the server, right? And so the server is storing that access token in session storage, which is much more secure than storing it on the browser. And so what I've seen is the general recommendation is, if you have control of your backend and you can like package them together, then try to do that, right? And another thing I wanted to mention is with refresh tokens, I've seen, there's a framework out there I think, it's called Angular OIDC, something like that. I've used it in a few posts, but it's an Angular OIDC project and they have support for refresh tokens, but they do it in like an iframe and they do it silently. And because of the same site cookie and third-party cookie issues that are happening with like Chrome and Safari where they're blocking those, I think that solution might not work anymore. So I think if you somehow have your IDP and your app on the same domain or same subdomain, then it will work, but the refresh tokens thing for me in the spa is like, people say it's a thing, I've never been able to make it work. So how does this all, does it, words? I've heard that Pixie or proof, what is it called? Proof. Proof for code exchange. That's it. Right, I have to like re-record videos because I got it wrong. Yeah. I really should be better at that. I do have a link here to explain what it is I'm talking about. Yeah, so do you use that at all? Like, is that something that you can use in, let's say you're just a front-end only site, is that something that an approach you would use and why would you use it? Yeah, so a front-end only site where you don't have control of a back-end, where you don't have a back-end that can do your token exchange and other types of validation. Pixie is designed to give you a more secure exchange for an access token. So normally, if you're using a back-end server, your back-end server has this secret that no one, you don't ever expose to the public in any way and that secret is the way that those back-ends can communicate with each other and say, hey, this is, I can prove who I am because I have this secret that we've agreed upon. And Pixie simulates that same kind of exchange on the front-end so that if you're in a spa world, single-page application where you don't have any back-end at all, you basically generate a secret on the fly that becomes the way of validating, like here's this random code that I'm supplying with the request to get a access token. The server that you're communicating with that's doing your off is going to accept that and keep that as part of that transaction so that later on when you get your temporary token and you want to exchange it for an access token, you can supply that same code again to say, yes, I'm still the same person that requested that in the first place and it could be more or less risk that something bad hasn't happened. Right, so in spa apps, the alternative is implicit flow and implicit flow means that you'll get the access tokens back in your address bar and the reason that that existed when we first started inventing a lot was because the browsers didn't have good XHR support and like course, right? Cross-origin resource sharing wasn't as much of a thing and so it was a workaround for that and so the recommendation now is from the OAuth committee and from Octas, don't use implicit flow, use off code flow and if you're using our SDKs, I think it's Angular 2, View 2 and React 3 versions for those, those all use Pixi by default. So if you were to upgrade those then you would just need to go into like your Octa app and check the authorization code checkbox and then you could use Pixi. I mean you could still use implicit but try not to. And then I think this is a good point from our friend Micah that part of the reason Octa doesn't allow refresh tokens as spas is because they're more easily intercepted and we have unlimited exploration on a refresh token. So what I've noticed is they're great for mobile apps and in fact, I've used Ionic app off the fair amount and I am Nick and if you set your access token to like five minutes what I've noticed is that library as soon as you get it, it thinks it's expired because it has like such a, you know it's windows like five minutes for drift time. And so the next thing you do it'll go and get a refresh token. And if you're on a mobile device works great. If you're in a browser, you get an error, right? So yeah. Well, I know that when I was messing around with Alexa I was trying to figure out which flow would I even use for that, right? Cause it's not a mobile app but it's also the flow is actually the same as it would be for a front-end site. So because you do at least with Alexa and Google Assistant you get redirected as part of their OAuth OIDC flow initially, but after that if you don't set up refresh tokens basically the first time your Alexa scale will work and the next call you do, it won't, it'll fail. So it becomes important to pay attention to when and where you exchange things. We have all that kind of like laid out in our developer docs, but I mean maybe you guys could show me like an example of how you would use it in a front-end framework. I don't know which ones are you really deep and are you deep in react, angular view? Which ones have you been playing around with each one of you? For me it's been view more recently but it has been, I don't know it's been a minute since I've implemented any view apps. I think Micah's probably more up to speed on Angular, right? Well, yeah, I've done certainly a lot with Angular a bit with React. I mean, that's what I love about J-Hipster is we support all three, Angular, React and View. And guess what? The code is the same on the client for all three because we do all the OAuth stuff in the backend, right? And so if you're developing an app where you might have multiple clients, right? That's why you might consider doing it on the backend. But another thing that I wanted to bring up was that as soon as I saw Micah's comment, I lost it faster. What was I thinking? Now you understand, I can't even pronounce things. It's morning time for me here in Kansas City, so my words come a little bit slower than normal. We're still live, right? Yeah, we're still live. Unfortunately, for everybody else, watch it. Okay, so I know that Matt, you said you've been touching Angular recently, right? Yep. Okay, do you guys have any? I recently made our samples work with Vue CLI because they were more webpackish before. And so if you generate a new Vue app with like the Vue CLI, it's a lot more compact, right? The scripts in there is kind of like create React app. So all of our samples just in the last month we've updated. They're using more of what you would expect. For instance, Angular uses Angular CLI, right React uses create React app and Vue uses Vue CLI. So I'm happy to demo any of those if you would like. Go for it, Matt. Yeah, okay. For random one, I wanna see your code, let's go. Well, let's get, so we got one vote for Vue in the comments. Let's see if we can get a couple more, but we are delayed like 15 seconds, right? So if I ask that. Yeah, that is more like eight, but yes. So we got one vote for Vue. David said he likes Vue as well. So we can do Vue, I have no problems with that. So share my screen here, right? And then close that one and close that. So I got this samples.js Vue here. And if you look at the remotes, you'll see that I have my branch and then I have the one from that. So how it works is if you view the read me, you should probably open that in a browser so it'll be easier to read. All right, no, don't do Xcode, nevermind. Well, what you can, no, nevermind. I was about to say there's a quick way to do it through MPM, but that was something else. So what there is is there's two folders here. There's custom login and there's octa hosted login, right? So the custom login uses our sign in widget and then the octa hosted login redirects to octa to login. So what the read me says is basically create a new app on octa and then put some variables in this test end file. So if I look at the test end file, it's got my username and password in there. So now you know that. And then issuer, client ID, and basically you can run and test these apps with a protractor, I believe, to make sure they all work as soon as you have that in there. So I have a tool called the octa CLI installed and I can do octa apps and see which ones. Well, I don't have any. So let's do octa apps create and with this name of that samples and we'll do a single page app. And I think, yeah, we'll make that the callback. And so now we have new values, right? So I can go into this test ENV. I'll open it up in VS code here. Make it easier. Oh, I don't like that. Textmate. And then I'll take this new fork here and put it here. And then this client ID, put it right here. And then you can go into like custom login and run npm test. And what this will do, it's pretty cool. First of all, test that your JavaScript app works, right, your view app, but then you'll notice samples Node.js express for right here. It also clones that. So it'll test that your access token and talk to a backend as well. And so it's starting up backend now and then it'll run the front end against it. Which backend? Is it one that you made or is it one that's automatic to generate? It's one of our other samples. So it doesn't make this already. That's because I don't know my password. So when that happens, then you go ahead and do octa what register and you create a new org. I'll do my octa run. And then as part of this, it'll prompt you to create a new password. So the password I had that password one didn't work on this org. A lot of times I just create new ones and throw them away and forget what they are. So that's what it's doing here. So this is the same experience. If you're brand new to octa, you create a new org and then it sends you an email and says, hey, what's the verification code? So now I got to check my email in front of everyone. This would be interesting. Well, you can also do this through the portal, right? So this is the CLI approach, but we also have the same process in the portal. But if you are UI adverse, then you could definitely do this approach, right? Both of them work. This one's a little faster because you don't have to click as many places, but it's cool because then it says, you know, if you want to set your password, go here. And then you can just type in your new password and you're basically locked in, right? And so then we'll need to update this test ENV here, right, to use this org now. So for that x-ray, I think back here, make that a bit bigger and we can go there. And then the client ID. All right, I don't think it created an app yet, right? So octa-create, app, octa-create, wanna do app-create, custom log in, single page app. When you say app, it's creating a registration for an app in octa, right? You're not creating the actual view app. You're creating an app for application registration. Okay. I already have a little play here, right? So I use this one and let's try it again. So it's basically gonna log in to octa, verify that like my username shows up and then make a call to the back end to verify that the messages are there. So then we'll dig into the code after this and I'll show you like how it's passing that access token. I can't get my passwords right. So what a terrible demo that was. No, it's real life. You mean you're human, Matt? Lies. Poor, but we can look at the code that's probably more interesting anyway. Well, and David, you also have something to show us later, right? Sure. I can flail on the keyboard for a while if we need to fill some time. So here's what the code looks like in the, in messages. So first of all, you know, log in, when you log in, it's using the sign in widget. So here's the code for that. It renders our sign in widget using some, you know, OIDC code here. And one of the things I just thought of is it could be my redirect URI, right? I'm using callback instead of login callback. So that's one thing you want to make sure is correct, right? And so I'll try it again after I show you this code. But here's our login widget, allows you to, you know, customize it if you want to, you know, have a different title or a different logo. And then here's our auth params for how it's displayed. And then once you come back, you can hit the profile page and that will actually grab all of your claims from this auth get user method. And then it prints them all out. So it's basically taking everything from your ID token, very similar thing and displaying those on a page. And then if you looked at messages, this works as it uses the view SDK to get that access token. And then includes that when it talks to the resource server back here. So let me just try to run this manually here instead of doing the test and see if I can log in. So localhost 8080. So I have a question real quick. It's not completely related to token validation, but you mentioned the sign in widget. So I thought that part of the value of using octas that you didn't have to build like sign in, it looks like you were able to customize things there. Is that, which kind of sign in flow is that and are there other options? So yeah, the sign in widget is basically designed for if you don't want anyone to leave your app, right? It might be a jarring experience for someone to go from your app to another URL, right? They might be like, what's happening here? And so by using the sign in widget, there's no like redirect, it's just in your app. But then the other thing that happens is people want to customize that sign in widget and it can be difficult, it's not too difficult. I think you did a CSS video on it, right? Whereas customizing all the CSS. So if you want to change the look and feel and still keep it in like a box, it's not too hard. But if you want to like move a button to the top or put it in a top, you know, navigation bar or something like that, then it can be difficult. And so that's where you can drop down to using our auth js SDK. And basically you're just writing JavaScript code that captures like the username and password, sends those to, you know, octa. And then you can still get back like an access token, an ID token, but it gives you full, you know, ability to customize the UI. So is that still an OAuth OIDC flow if you're not redirecting? No. Gotcha. Okay, so an OAuth OIDC flow is where everything's hosted on octa side and you'd be redirected to your org at octa. And then that's a sign in page that you're presented that you can do some like customizations to, but if you want to do full fledged, then you want to not do that flow and that's when you reduce the widget. Is that correct? Right, and there is some API calls that won't work with third-party cookies, right? Cause a lot of these browsers Safari started doing it like a year ago and I think Chrome 85 does it pretty aggressively where third-party cookies won't work. And so if you're talking to octa on a different domain than your domain, then you're gonna have some communication problems there. So one of the things you can do with octa is you can set up like a custom domain, right? I think I set up id.matrable.com and so I can use that to log into my site and then I can host my site on matrable.com, right? And so that's a workaround for third-party cookies and you're gonna pretty much have to do that with any identity provider, right? It's not really an octa thing. It's just the nature of using a third-party and one of the things I learned yesterday, which was like, or two days ago, I was like, what? It doesn't support that. So Cyprus, right? Cyprus is a well-known like UI testing framework for JavaScript frameworks and it doesn't support actually going to another domain as part of your test, right? Like it blocks it. And so there's an issue out there that's like, hey, we can't test any OAuth flows unless you allow us to do that, right? And so it was interesting for me. Have you run into anything special like that, David, when you've been messing around with some of the integrations in front end? Yeah, and talking about Cyprus in particular, I think I saw some internal information we were talking about that earlier and I forgot to respond, but I actually had no someone who works on the DevRel team at Cyprus and who has created a sample project for octa and it's pretty cool. And so the way that they have incorporated octa into their test workflow is basically doing a, kind of like our auth SDK does, it's making a direct call to octa to log in and get a token. So getting an access token directly from octa so that the rest of the application will work as intended. So just FYI there, there is a way to get Cyprus to work without having to. But it's a workaround, right? It's a workaround. It's not like the same kind of thing where you redirect and do those kind of flows. All right. So it looks like we have a question here from a viewer. Did you wanna talk that on the screen there, Heather? So not a token validation question, but a storage one. By default octa's JS SDKs is local storage, right? For tokens, what are your thoughts on this approach versus using closers and storing the access token? Such as using web workers first of all. Yeah, we touched on that earlier. I don't, I'm not against it. It would be convincing our SDK team to support it or creating a pull request and then and adding support for it that way. And if you do that, I'll send you a T-shirt. So I know that I had also passed this question on to Erin Park and you said that there really isn't a good best practice solution for this, but mentioned that like the web worker option that you said map is pretty promising there. Yeah, and then, you know, what I always say is if you have a backend, like I've done a lot of examples with Spring Boot and Angular and Spring Boot and React and what I've learned, at least in the Java world and I realized this is very different in other worlds is people typically like to deploy their backend and their front end in the same artifact, right? In the Java world, that's a jar, right? And so when you tell them, hey, here's this Angular app over here and there's this, you know, a jar over here and you deploy this to a CDN and you do your authentication here and then you talk to your backend. They're like, yeah, but can I just put them together? And then you're like, yeah, you can actually put them together and it's more secure because then you're dealing with that client secret on the backend. So if you have a spa and you're like, how do I make this more secure? The answer is rip the authentication out of it, right? And make it work with your backend and just use cookies, which we've been using for what, 25 years now? And they've worked just fine for keeping that state and making it secure between the backend. You know, it's interesting. I remember the first time I saw like a good single page app that came out and the promise was everything's just right here. You don't even really need a backend and you could just do everything here. And I haven't seen at least in my experience with enterprise level solutions, that's still the case. It seems like we usually hook everything up to an API that our company controls and end up doing some of that chatter and not having the entire process right there. However, I do understand that there is an option for nodes. So if you are a JavaScript developer and you don't want to learn Java or .NET or PHP, then you can still do things in node and have node be the one that handles that token validation, is that correct? Yep. Yeah, node is just like any other backend. So you can do your token validation and have your backend node is your backend server. So it can do the communications with other resources, other third parties, so that as Matt was talking about, if you want your front end to just only have a session and like a session cookie and it communicates with your backend server, if it doesn't need to reach out to other APIs that live elsewhere out in the world, which is far more complicated anyway, with all the cores and other types of restrictions, then yeah, some type of backend is going to be a simpler scenario and easier to work with. But there's still calls, right? At the end of the day, whether it's a front end framework or backend, you're still going to be doing things over the web, right? So there's still inherent risk in some of this stuff, but the difference is that all of your script literally is something that you can right click and inspect and look at in a website, whereas a .NET one is completely compiled and then put to the browser. Of course, I'm running into this now because in the .NET world, Blazor has come out, but there's two versions. There's Blazor server side, which uses like web calls and then there is Blazor WebAssembly, which now has the exact same issues that we're talking about here when it comes to token validation. So even though I can build a .NET app in Blazor WebAssembly, it's basically like I built a JavaScript spa. I mean, that's pretty much the same because you can still right click and inspect and take a look at stuff. So I have to now follow the same kinds of concepts and separate when I validate that the token is really real and somebody isn't trying to spoof me. Well, I think something too important to remember about cookies, right? People are always like, well, cookies can be stolen too, right? Just like an access token, but cookies have recently had some enhancements where you can have it be secure only and you can have it be HTTP only, right? So that means that your JavaScript can actually read the cookie. And so that makes cookies a bit more secure there versus having a compromising script that can talk to your local storage, you know? But it's a hard problem because there's a sense of, well, what's the recommended practice for OAuth? And it's like, make your access token short-lived. And then you're like, but I've got this spot and you're telling me I should make everyone log in after five minutes again and again. And you're like, yeah, it's like a terrible user experience and then the work around like, make your access token live long, right? And it's like, well, that's a bad security experience. So on the front end, you have to compromise that way, which kind of stinks. I think a lot of the mobile or the social sites like Twitter and LinkedIn and Facebook, they all use like a week-long access token, right? And on the mobile apps, it's not a problem because you can use a refresh token, right? And that usually happens automatically. The same thing with any backend one as well, is that we can just refresh tokens and set it up and be good to go. Right, yep. And a lot of the frameworks, like you shouldn't have to worry about this stuff, right? You as a developer shouldn't have to worry about your access token expiring and trapping that and getting a new one, right? There should be SDKs or frameworks like Spring Security that handle all that for you. And for the most part, there are, but you might find issues. And even with ours, we're doing our best to make it transparent, but you might find bugs, right? So we just encourage you if you have any issues, right? With refresh tokens to file an issue in any of our GitHub repos that you're using and we'll try to fix that because we really want the best experience for the users, right? Like we fight for the users. Yes, we do, absolutely. I know that for me, moving from, I said, not really moving, but really truly expanding to a full stack knowledge base for me, I found this particular thing to be hard to conceptualize because I have lived in a backend world where I always can go and validate. I can always make sure that everything is secure. And it's really kind of terrifying to work solely in the browser. I feel like there's a lot here that is at stake, right? Especially as a developer, it seems like we are held to the expectations that we know when to speak up about, hey, we're not following a good standard or hey, this is possibly could be compromised. It seems like the onus is on the developer now to have the knowledge, whether the frameworks handle it for you and SDK handles it for you. You seem to still have to have the knowledge when it comes to the decision makers out there about what should be done. So I think I understand the constant questions that we get about, well, what should I do? Like, what does it mean to be secure as a JavaScript developer, what does that mean? You know, like how should I be thinking about this? Should I save my token? Should I not save my token? What happens if somebody suddenly closes their browser and then pops back up? Should I instantly log them out? How long should it go? Should I log out their whole session, like their whole entire octa session or should I just forget about the token in my local app? That's another question. Have either of you dealt with single sign-on versus just your app being logged out but everything else being logged in? Well, one of the interesting things we ran into with Jay Hipster when I first implemented the flow there was that if you logged out, all it did was kill like the server session. And so if you clicked log in again, it would redirect you to octa or key cloak and log you in and then you're right back where you started and people are like, no, I wanted to log out and log in as a different user, right? Cause they're testing, right? So they want to log in as an administrator and then log in as a user and see what the difference is. And so what I used for the first year and I got away with it was like, if you logged out of, let's say you used, you logged into RunKeeper with Facebook, right? If you logged out of RunKeeper and that logged you out of Facebook, you'd be pissed. You'd be like, what the hell just happened? I got to re-log in. Like every time you log out of one of the apps, you got to re-log into Facebook. And so that worked for the longest time and people were like, okay, that makes sense. But, you know, sometimes you really do want to log out and so that's where I implemented where you go to our login or log out endpoint and pass that ID token, that refresh token. So I think, I don't know if that answers your question but I think it's like single sign-in is you never really want to be logged out, right? Well, I mean, from everything. You're like, you want to log out because you're trying to test stuff, right? You're trying to test different users and scenarios. So I guess that was really confusing, right? I had lots of questions about that over the past week is that what does log out mean to Okta? Do I need to hit your endpoint or should I just forget about the token? Should I just like remove it from my app so that my app no longer sees it? You know, like, so when it comes to, you know, what happens if I hit the Okta log out endpoint? Does that mean that all of my apps are now signed out or does that mean that just my current app is? No, just your current app because it uses the ID token, right? So it knows that you got that ID token for that app. Okay, but if you have an access token, can you log out? Now, our log out endpoint, there is RP initiated log out, which I haven't been able to get work to work, but I know Brian Demers did a spring boot log out options post on that and he uses that. And that's actually from the server side, hitting like Okta. And so the client never sees anything and logging them out as well. Okay, so then in your client app you wouldn't necessarily ever worry about that. You would just pass the log out requests to your backend and say, hey, backend, go log the user out. And so I think it really only applies to developers like why you do want to log out, right? Cause once you're in production, like take us, right? We're Okta employees. We log into Okta.okta.com and we never use a different username, right? So we always want to stay logged in, right? Like it's a pain when we have to re-log in. So we never really want to log out. But as a developer, you always want to test these different scenarios, right? So I don't know if it's used that much in production, but for development it is. So does that mean that when the token expires is that just for your current app? Or is that for you as a user across all Okta apps? No, it's just the current app. Just the one that you just logged in with, yep. Oh, that's good to know. So then expected behavior is that disconnected. This is really an isolated instance, which is why you register an Okta app for every like view or Angular app that you have, right? So that it's separate from the rest of your org. Right, and there's also API tokens, right? And so you would use those with our management SDKs, which are typically different than our JavaScript framework SDKs, right? The management SDKs are usually backend only, right? So there's a node one, there's a Java one, there's a .NET one. And on those you typically use a API token, and those are just tied to that token, right? It's not really a session, it's not on behalf of the user or anything like that. It's this app TalkStock done, does user management like updates attributes in a user, maybe delete to user, maybe add some to groups and stuff like that. And I've actually had questions from people that are like, can you show me how to implement API tokens in my app? It's like, I could probably point into some StackOverflow articles, but I haven't done it myself, right? Like I think it's a cool feature. Like if you could have API tokens and you could support OAuth, like that's a pretty nice app because then you're kind of like Okta, right? And that's a great thing, but I haven't implemented API tokens on them. I think it's terribly difficult, I just haven't done it. Yeah, I've done a little bit of that, but that's because, you know, I live in that net world, we do a lot of API everything. So I appreciate that. What do you think is the most challenging aspect of thinking about managing tokens from a front-end, like framework perspective? How do you think about it? I don't, that's why I use Okta. I love that. Don't think about it. So if, but if you didn't use Okta, like what is the value there, right? Because there's lots and lots and lots and lots of GitHub repos that do all sorts of things, right? So then what is the value of like, I don't know, shipping that away instead of just finding something randomly on the internet? The argument that I hear with Jay Hipster, right, is people often wanna switch to doing the authentication on the front-end and making the backend, the argument is they want the backend to be stateless, right? And the reason they want it to be stateless is it's easier to scale stateless or is it? Like that's what we've been told, right? But like there's not a lot of proof that it's actually better. I mean, there's tools now with sessions that you can, you know, distribute them and they aren't as terribly difficult. So, you know, I believe that stateless might scale better but I've been meaning to write this blog post for like a year now that's like, hey, Jay Hipster has a few different authentication mechanisms, one is JWT, right? Jots and that one's stateless. And then there's OAuth, which is not. And then there's Session, which is not. And so if we were to hammer those with something like Gatling, like who's the first to fall over, right? Maybe it's the JWT one because it's actually, you know, processing JWTs, issuing JWTs is doing this cryptography and, you know, it doesn't have, it has to deal with more like in its actual system. So it's something that I want to test, right? And I actually, I spend a lot of time in the Jay Hipster issues of people being like, we should do it on the front end, right? So there's still a lot of people that want to do the authentication on the front end like we're talking about here. And I think when you get into maybe really high scale and doing like lambdas and serverless and your back end is trying to be not that smart and your front end is trying to be smart then you're going to be kind of shoehorned into putting a lot of logic on your front end. David, have you ever done any like deployments to like a host, like Heroku or Azure or Amazon at all with any. So do you find that you can just deploy it and it just works or that you have to really set things up so that token you can even get where it needs to go? Yeah, there's, well, let me try to think of some scenarios but when you're, we were just talking about serverless, Matt mentioned serverless stuff and there's work that has to be done to configure those functions to allow certain domains to be able to think to try to lock down security on any kind of end point when you're talking about some kind of back end API or serverless API you want to restrict who can call those APIs or have like a cores policy and there's just a lot of work to be done. I like services like Netlify that hide a lot of that complexity for you so that, hey, this is my domain, this is my website that I'm trying to deploy. These are the sets of functions that I want to deploy as serverless functions and behind the scenes it's doing all the work to configure those individual functions and set the security policies and all that kind of stuff and I really appreciate those types of services where I don't have to worry about those things, I don't have to think about them, I don't even fully understand them all but I can appreciate that they're doing a lot of stuff for me that would normally take a whole lot of work and to do the same kind of thing if I were to do it on my own. Oh, absolutely, I know each of them are very different. I have run into a little bit with deploying some of the web assembly stuff for Blazor again which is basically compiled down JavaScript and shipped to the browser that way with cores, which I'd kind of forgotten about because I had to really mess with it a whole lot and it seems like certain hosts just really lock that down and make it a little bit more difficult to turn on. I found that nine times out of 10 some of the AWS Lambda stuff decides that they want to hide a whole bunch of controls or you have to just inherently know where they are. That's harder. However, when I had to deploy some of the stuff to Azure it's actually not that easy either. So have you, and either one of you run into one that just kind of has like just a really quick cores enabled option for that host because everything has to come from like where your DNS is, right? In order to make sure that you don't have any sort of errors that way. Yeah, so I was just talking about Netlify. Under the hood uses AWS Lambdas and so they do all that configuration for you based on your current environment, your domains or domains that you are deploying, that you're hosting. And it just magically, the one button that you press and it all happens for you. And I'm not as familiar with Heroku and some of these other services, but I know they do a lot of that kind of thing for you as well. So one thing I wanted to bring up was when people do deploy to these services to get this question a lot is they get everything set up and they run it locally, it works fine. Let's say they're using Angular and they're using like Webpack.dev. And then they deploy to something like Netlify and they log into Octa and it comes back to their app and they get a 404. And they're like, what the heck just happened, right? Why am I getting a 404? It worked fine locally. And the reason is because single page apps need to have all requests sent to index.html, right? And whether it's a 404 or any 401 or anything like that, that single page app needs to handle it, right? And so Netlify makes it super easy and so Netlify makes it super easy, right? There's like a redirect file you can add, Firebase makes it really easy. The other one I've used is Heroku, like those all make it so you can add like a file to your app and then it does everything for you, even does like security headers and stuff like that versus like AWS, oh my God, so painful. It takes like 20 minutes and you have to go set up a Lambda just to add like the security headers. And so yeah. It's not too dissimilar in certain parts of Azure as well. They are working on it, getting it better for sure. But it's interesting like you think that you understand how things go when you realize that you've just been doing the same host provider, you've just been doing the same frameworks or maybe it's kind of like the TypeScript thing, right? I hadn't touched just raw JavaScript in hot minute. And then I was like, whoa, I mean, some of this stuff is built into TypeScript, a lot of auto completion is as well into my IDE. So I take a lot of highly configured things for granted sometimes. So it's easy to become overwhelmed whenever you're plugging in authentication into an app because you think it works here, why doesn't it work over there? It is a constant question. How come it worked on Azure but it doesn't work on AWS now? Like what's going on here? Because at the end of the day, they are still the gatekeepers of what is allowed to be, what is allowed to call into it, what is not allowed is still something that is not within your app, it's within your host provider, right? And so you have to understand a little bit about how that goes. I think it's a great transition into why the demo that I did earlier did not work. And so what I've discovered is how to make it work and I've discovered some issues that I made along the way. So if you wouldn't mind, I can share my screen and show you what those were. Yes, please. That's great. While you're doing that, I was gonna say one of the mistakes that I make almost every time when deploying something into production is I forget to add to Okta the domains that my production domains. So when I try to log in, it doesn't know who I am because I'm coming from a different, something other than local host. And so those are, by default, Okta doesn't allow just any domain to request for, you know, do an OAuth flow or request for tokens or any of that kind of stuff. So you have to explicitly add the URLs that you're working with for your production app. Right, and that's not an Okta thing, that's an OAuth thing, right? They require that you specifically spell out with no wildcards the exact URL, right? And so let me show you this. So I did some debugging and if I enter my credentials here, what happened is down here, you'll see in cores error, right? It's been blocked by cores. I don't know if you can see that, but what needs to happen and I think this enhancement is in our Okta CLI but maybe it hasn't been released yet. Because you have to go into the trusted origins and add one for local host 8080. I take a name of whatever you want but then you have to put it down here. So then you do that, right? And you have that in there. So then you're like, okay, this should work now and you sign in and then it comes back and you're like, what? And so this is a very common problem. I see it a lot from developers and this description isn't great, right? The redirect parameter must be an absolute URI what David was just talking about. That is whitelisted, you know, that's not inclusive language. So we're fixing that in the client app settings and we actually, we're even rolling out an enhancement that tells you what the redirect URI your setting is because up here, it's actually in the URL. So if you scroll along enough, you'll see a redirect URI right here. And so this is what needs to be whitelisted. You'll see we have login callback in there. And so if we go look at our app and if you remember, I actually set it to 8080 callback, right? There's no login in there. And so I actually have to go in here and I could add another one, but that needs to match, right? And especially because if you look at the view app, that's what it expects to come back, right? And so I could certainly do callback but I'd have to modify this here to remove login. And then I'd also have to go into this config here and remove it there as well. So by default, it just expects that one to be there. And so once I have all that set up and I can actually just refresh, right? And it's that same request and it comes back and everything's working. And then if I go to profile, I'll see everything from, I should see everything from the access token or from the ID token, right? So that's all my claims in there. And then if I was to go to messages and that backend was warning, then that would work. So one of the original examples was just like run npm test. So if I run that now, it should work. It uses protractor to drive everything and actually sets up that backend as well. So those are things that developers that use Okta struggle with all the time. And I think it's funny that I'm an experienced person and I still struggle with that kind of stuff. There's a lot of different options for everything. I think that part of what is great about our product is that it's very flexible and it can do a lot of things. Part of the problem with our products is that it's flexible and it can do a lot of things. And when you're trying to keep all of that in your head it's actually kind of a lot. So if anyone of us can definitely become overwhelmed with it, imagine, you know, how many versions of spring have there been over the years that maybe work a little bit differently? That's part of why you did Jay Hipster, you know, to make things even easier for interacting with it. I mean, I've got so many versions of what C-Sharp can do. But I still feel like the biggest struggle is gotta be all the different JavaScript frameworks that are coming out every five minutes and how they want to handle things. Some of them are more robust, right? And have a little bit of that security built in. And some of them are like, nah, we just wanted cutesy names for things, you know? I do want to dispel that myth, though, that there's a new JavaScript framer that comes out every week because if you think about it we have the big three, right? Angular, React and View. And they were like five years old, which in JavaScript land means they're like grandparents by now, right? So I think, you know, even though there is new frameworks like Svelte and others coming out, we've had a lot of innovation in Java recently as well. Like Micronaut and Quarkus are new frameworks that use like, you know, new things that people didn't think about before. So I think there's innovation happening everywhere and even .NET 5, right, is new and exciting as well. And of course, then there's within those languages or frameworks, there's also what kind of apps? Desktop apps, do you have mobile apps? Do you have spots? Do you have APIs? You know, there's so many different kinds now. I mean, I've got web workers, all sorts of different things. So each one of those are going to interact differently with ACA. So on top of the language, there's also the type of app that you're doing. Even within like the most recent templates there are, which is part of why we need more open source community contributions, right? Is to say, hey, we figured out how to do it this way and share that with the community, like on our forums or you can always email us, you know, devrel.ox.com. We can always talk to you about how something might work. Just because we don't always have all the answers right now doesn't mean that we can't be your best chance of having like at least a connection to our engineering team, you know, so that we can find out what those answers are and make it a little bit easier to share. Right, one thing I'd like to point out is that's what we really try to do with our blog posts, right? Like we have a lot of samples for the various things, but you know, if you want to do something that's not traditional, then we typically write a blog post and show how to do that. And we try to have GitHub repost for each blog post. So I think we're up to like 200 and something now, but we also have a toolkit site on octa.com that highlights a lot of those samples that we have out there. And what we'd encourage you the community to give us is ideas for blog posts that you would like to see. Like you've tried to do something, maybe you couldn't figure it out or, you know, you're trying to do some filtering in GraphQL or Wear Clause or something like that. Like things that we could write about and provide a sample for, we're happy to do, right? Because it's tough to come up with new samples all the time or new ideas to write about, you know? Yes and no, right? There's lots of ideas of new things, but it may not take hold in the majority of the community, right? So you've experienced this. If you write about something that's in beta and then, you know, four months later, they change everything. Then you're like, do I update that blog post or do I take it down or like what? Right now I'm dealing with Q-Sharp. So that's quantum stuff. Like are we really going to use that, you know, at the website for Jamba Juice? Probably not, but you know, it's interesting to me. I feel like it's good for all developers to know about. So I think our blog is a good mix of the awareness around newer stuff coming out so that you're prepared and then, you know, solving different kinds of domain-specific problems that exist right now if you're having difficulty looking. And usually one of us will figure it out and throw it up there, but yeah, please let us know about it. And don't be afraid to ask questions on our stream. We're just here talking to each other because it's better than talking to ourselves, but we'd love to talk to you too. So don't be afraid to ask. And David, do you have anything that you want to say before we wrap up? Sure. We were talking about Sevelt earlier and that's definitely on my radar. That's one thing that I would like to dive into and create a blog post or two about. So that's looks like a cool alternative to some of the other frameworks that, you know, every framework that comes out that has its pros and cons and, you know, it's a reason for existence, you know, and they all have valid reasons, you know, these authors that come up with all these frameworks. If they make it past, you know, just them themselves using it, there's usually a pretty good reason for why that thing exists. It solves a particular problem for a particular set of people or whatever. So one thing that I heard a colleague of ours say years ago is like strong opinions weekly held. And that's kind of the approach that I've tried to take with the JavaScript community is, you know, hey, there are things that I really like. I have preferences, but the things that people are coming out with all the time, well, they have valid reasons too. You know, there's reasons, there's pros and there's always pros and cons or trade-offs or, you know, a particular niche for that thing that it solves. So, you know, I try to keep an open mind. I think for me, it's a strong opinion, strongly typed. I will die on that. So I have a good tech thing because I think it's funny on this call. So have you heard any background noise from me while we've been doing this? No. Cause I've had not only a chainsaw running like within 10 feet from me, but also like there's a guy mowing the lawn out there right now. And so I'm using this tool called Chris, chris.ai, and it's really awesome for like killing the background noise when you're doing calls like this. It's changed Trish, my wife's life because she has an office in the middle of our house and the kids will come in and like make breakfast or all stomp in and, you know, be bashing stuff around and she's on a call like this. And she's like, would you just be quiet? And so since she's got Chris and installed it, it's changed her life. She's like, you can do anything and no one will hear any of the background noise. So I highly recommend it if you're working from home, which most people are these days and trying to live my life. I do give up. Yeah, I give it a thumbs up too. I've been using it for a few weeks. And yeah, almost every time I would start to record or have a do a stream or whatever, the guy who mows my yard will show up and unload right outside my window. You know, every time. I know that Zoom has a little bit of noise cancellation built in and some others might, but this is for everything. Anything that uses your mic, right? Right, yeah. That's cool. I have not installed that yet on my PC, which I'm on right now, but I definitely did for my Mac because that's usually my travel companion is I take my MacBook Pro everywhere. But at home is probably when I need it the most because that's when the dog is barking or I have the loudest HVAC in the world. It comes on and it sounds like a Mac truck is coming by. So it definitely worked on my laptop. So I need to install it here. I did notice, I think Zoom had an update recently where they killed any echoes, right? So like if we had a Zoom call and I was showing you how to work stream yard, I'd have to like mute Zoom. And I did one of these last week where I didn't have to mute Zoom and there was no echo even though there was like two speakers. So that's pretty neat too. That's awesome. Thank you guys for answering all of my silly questions as I'm much newer to doing front-end stuff. And if you guys have any questions for us, like again, please hit us up at www.doctor.com or you can hit us up on Twitter at Octodev as well. And we also have a YouTube channel. So if you're interested in checking us out there, we have an OAuth happy hour every other week that we don't do this group Twitch stream. But other than that, thanks for joining us. Thanks, Al. See you later.