 Hello, friend. Automating things on a computer can be challenging. If you've ever written any amount of code, even a single line of code, you are a real developer. And don't let anyone else tell you otherwise. In this tutorial, you're going to learn how to build serverless functions with JavaScript, deploy them to Netlify, and secure them with Okta. Let's get started. Serverless computing, sometimes referred to as functions as a service, is an on-demand approach to providing back-end application services and perhaps an API. The serverless architecture is an excellent solution for many use cases where an application needs a back-end, occasionally or periodically, or maybe a back-end that can scale to meet demand, like a big spike in usage or traffic. Netlify that we're going to be using in this tutorial is a hosting company that dramatically simplifies deploying websites and serverless functions, which they call Netlify functions, with continuous integration and other really awesome features. Okta is an identity and access management company that makes adding things like authentication and authorization to your applications very easily. Before we jump into the project, there's a few things that you're going to want to have on your machine, on your system. The first of those is Node.js. I recommend version 12 or higher as of this recording. Version 12 is the latest stable and long-term supported release of Node.js. You can go to nodejs.org and click on the download button for your operating system. However, if you are running on Mac or Linux, I highly recommend that you go find MVM, the Node version manager, and install that on your system first. MVM is a really great command line utility that allows you to install versions of Node, including you can have version 12 installed on your system and version 14, if you want to experiment with some of the new features coming out in the next release of Node, and you can switch back and forth using MVM. Another thing you're going to want to have is a Netlify account. You can go to netlify.com and sign up for a free account. There's a number of things that you can do with Netlify that cost you nothing. And the examples of this tutorial that we're going to be going through will not cost you anything. Another thing that you're going to want to have is a Octa developer account. This is also free and it's free forever. You can use this for any of the proof of concepts or small applications or anything for up to a thousand monthly active users, which is, you know, fantastic. I use it all the time. You're also going to want a good code editor. And if you don't already have one, I recommend Visual Studio Code. I use this all the time. And I think it's one of the best JavaScript and Node.js debugging tools and editors available. All right, so let's get into creating some code. So we need to create our serverless project to get started. You want to open up your command prompt or your terminal, depending on which type of operating system you're on, and change to the folder where you normally store your projects. For me, I install, I work on projects in a folder called projects. And in this example, I've got a folder named tutorials. So start by creating a directory. If you're on Windows, you will use the md command, but I'm going to use makeder because I'm on Mac. And let's call this the secure serverless tutorial and then change to that directory to start any new Node.js project, which is we're using node as a starting point. We're not building a node application. We're building a front end application that uses some node type things with the serverless functions. But any type of project that uses node and node modules and the ecosystem that's around Node and MPM, we need to have Node.js installed. So one thing you can do is type in node-v at the command line to see if Node is actually installed and working correctly on your system. If you get an error with this command, then that means that either you don't have Node installed, or maybe you just now installed it and you need to restart your terminal or your command prompt, or worst case scenario, you might have to restart your computer. Hopefully we're beyond those days where we have to restart our computers every time we install something, but it still happens sometimes. Alright, so with Node installed, Node comes with the MPM, the Node package manager, and we use MPM to initialize our project. So MPM init-y-y argument tells MPM to just whatever the defaults are, create a project file with those defaults. So it creates a file called package.json in your folder, and depending on your defaults is going to populate this package.json with those. The package.json is a way for Node to keep track of dependencies, such as you want to install an external library to use in your project. When you use MPM to install that, it's going to add a reference to that dependency into your package.json file. And speaking of dependencies, that's what we need to do next. So there's a number of things we need to install. One of the things that I install first before I do anything else is install ESLint. ESLint is a linting tool for JavaScript. It helps us to identify mistakes in our code, common mistakes, maybe unused variables. There's lots and lots of rules that can be configured with ESLint to help you to write better JavaScript code. And we all know we need all the help we can get when we write JavaScript. So I'm going to install this as a developer dependency. We don't need ESLint running in production, so I'm going to use the dash-save-dev argument. And I want ESLint. And me personally, I use ESLint config-reverent-geek. This is my own set of ESLint rules that help me not only with some common mistakes that can happen with JavaScript, but also the way that I like my code to be styled. So you can have styling rules as well as coding and syntax rules. So let's let that install. And then next, we need to install our production dependencies. And first thing we're going to install is octa sign-in widget. And I'm going to specify version 4.2. And the reason I'm specifying an exact version is I want, you know, as long as this tutorial lives on YouTube, which could be forever, I want this tutorial to continue to work. And the way we can make sure that it continues to work, even though libraries can change over time, is to, you know, start with a very specific version as of this recording. So we need the sign-in widget. We're going to use Axios, which is an API Fetch library. You know, use it to call APIs. In this case, we're going to use that to call our own serverless functions. A lot of modern browsers have what's called the Fetch API built in. But just for compatibility reasons, we may, you know, in case you want to build a serverless-based application in the future and you want to deploy that and you don't know what kind of browser somebody may be accessing your web application with, Axios is kind of a fail-safe way of doing those client-side API calls. And then we're going to install Netlify-Lambda, which is going to help us with our Lambda functions. I should say our serverless functions, which under the hood, you know, I mentioned before that Netlify calls these Netlify functions. What it really is, is a wrapper around AWS Lambda functions. You may have heard of serverless and you may have heard of the term Lambda use. Those are kind of interchangeable as far as like the AWS, the Amazon web server ecosystem goes. So if you were to create and deploy AWS Lambda functions, which you can do, there's a lot more work involved. There's a lot of configuration, a lot of setup. And that's one of the reasons why Netlify is such a great platform, is that it takes something that can be really challenging and hard to configure and set up and makes it really, really simple and easy. So Netlify Lambda, we're using 1.6 and then we're going to also use Parcel 1.112. Parcel is a bundling tool. You may have heard of a tool called Webpack. Parcel is very similar to Webpack, has a lot of the same features, but with Webpack there's a lot of configuration. Again, I'm picking a tool that is kind of the easiest to start with. Parcel, without having to specify any configuration at all, will kind of recognize the types of files and things that you have in your application and will package up your HTML and CSS and JavaScript and all the dependencies that are used by your application front-end and bundle those into a, you know, a lot of times it's a single JavaScript file that you can, that will automatically be updated in your front-end code. So great tool. Also, we're going to be using modern JavaScript in our front-end, you know. So syntax like the import statement and arrow functions and async and await, which are great. I love those features of JavaScript, but again, not every browser supports those features. Older browsers may not support things like async and await. So Parcel is going to do the job of transpiling our modern JavaScript into an older syntax, equivalent syntax, that can run on across most browsers that exist today. All right, so let's install those dependencies. May take a minute or two. I'm going to take a sip of a hot beverage. NPM is amazing. Could have took a nap. Well, that's the way it is with NPM sometimes. Now, there is one other dependency that we want, another developer dependency, something we don't need for production. And that is RemRaf. RemRaf is a cross-platform developer dependency or utility for removing files and directories. And the reason we want RemRaf is part of our build process. So as we want to build a new version of our web application, our front-end code and use Parcel to bundle all that stuff up together, we want to clear our distribution folder. So in a nutshell, all the code that we create for our front-end application, it's going to get packaged and bundled and all those kinds of steps and put into a folder named DIST for distribution. And we're going to clear that folder out before we start our build process. All right, so we've got our dependencies. We've talked about what each of those dependencies do. By the way, this video is based on a blog post that I've written that goes through. So basically we're following along with this blog post. If you want to also pull up this blog post and follow along, I'll have a link to it in the description below. And you can pull that up in your web browser and you can kind of follow along with me. And that way you'll be able to copy and paste some of the code instead of having to type it all in, which will save both of us a whole lot of time. Because you don't want to watch me typing for hours and I'm sure you don't want to. We're beyond those days of trying to retype all the code that we read in a magazine or something like that. We live in a great age for computing. All right, so now I want you to open your project in your editor of choice and start making some code changes. So I'm going to use Visual Studio Code, which I can call code from the command line, which is really convenient. If you don't have that ability to use code from the command line, you can open up Visual Studio Code if this is what you're using. Go to view and go to command palette or shift command P, one of the other, and you can search for shell command to install code in your path. And that way you can call type in code at the command line and be able to launch Visual Studio Code as your editor. Really convenient. All right, so right now we just have our package JSON file, our package lock file, and some node modules. So I want you to open up package JSON and look for this scripts. And I'm going to remove the test script. And I want to clarify or just state that testing is extremely important. We're not going to cover any tests in this tutorial, but I've got another blog post on testing tools that are available for JavaScript and Node.js. I'll put that down in the link below description below and highly recommend checking out tools like Mocha or Jest that can add some test coverage to your application. So the scripts that we want to create, we want to create a dev script. And this is where we'll run our rim raft utility on the distribution folder, the dist folder. And then at the same time, after that command finishes, we're going to call parcel to transpile and package up the application. And we're going to point it to the client folder index.html, which we'll create in a little bit. I also want to add a script here just specifically for build. So for the build script, we're also going to use rim raft dist. And this time we'll call our netlify lambda and use the install command on netlify lambda. We'll find all the netlify functions that are in the project and set up any dependencies that they have. And then we'll call parcel build and that's the two we need. Now another thing that I want to add, earlier I installed ESLint and my own ESLint config library. I want to add an ESLint configuration file to this project so that ESLint knows how to use that in the project. So I'm going to switch back to the command line and I'm going to create a file called ESLint.eslint.rc. I'm sorry, I'm all over the place. ESLintrc.js. Now I can never remember the syntax. Well first of all, if you're not on a Mac or Linux, if you're on Windows, that touch command is probably not available unless you have the Linux subsystem installed. So equivalent command for Windows might be to like echo out a ESLintrc.js. And that would just create a blank file. Touch is just a nice way of creating an empty file. Okay, so I can never remember the syntax for what goes into this ESLint configuration file. And so one of the handy things you can do with MPM is you can launch the documentation for any MPM module using the MPM docs command. So MPM docs and I'm going to pass it ESLint config reverent geek. And that's going to launch a web page for the documentation for this module. And I know I have this one here that is like the base configuration, but I also have these alternate alternative rule sets. And one of them is specifically for Node.js. And that's the one I want to use. So I want to copy that and go back to my Visual Studio Code project and paste that into this module. And one of the things that it's going to complain about is I need to declare use strict mode at the top of every JavaScript file in a Node.js project. This is just one of my personal things that I like to do. Now that I'm thinking about it, this is going to be a front end project too. It's not just Node.js. We're doing front end work really for the most part. So maybe I need to switch to this browser version and that will be better. Well, we'll see. We'll see what happens later on. Maybe I'll put this inside our client folder when we create that. All right. So the next step we want to cover is creating our octa application that we need to secure everything that we're going to do going forward. So adding security to any application such as account registration, logins, password policies, profile management, email confirmations, those kinds of things, that's no trivial task. And getting any of those steps wrong could have disastrous effects where you're exposing your accounts or your client data to hackers. And that's where a service like octa is makes your life as a developer much easier. So to complete these next steps, I want you to create a free octa developer account if you don't have one already. And to do that, you're going to go to developer.octa.com and click on this sign up button. Click the sign up button or click login and pause this video and come back after you've created your account. Intermission. All right. Assuming that you have your account now, I'm going to, and you're probably already logged in. I'm going to log into my account and you're going to click on applications. Click add application. And then you're given a set of choices, native single page app, web or service. In this tutorial, we're essentially building a single page application. It's just a JavaScript front end to make calls to our APIs. So that's the type of application we're going to choose. Click next. And then here on the application settings, you can change things like the name and the base URIs, the login URI. Let's name this something like secure netlify demo or tutorial or whatever. I'm going to name my tutorial demo just to make sure that I'm not creating two of the same name. I may already have one out there called netlify tutorial. And I want you to change the login redirect URI to remove this path implicit slash callback. So it's just going to be the local host port 8080. And you can come down here and click done. And it's going to bring up this general settings page. It's got information about your octa project. And I want you to copy the value that's in this client credentials box called the client ID. You're going to need this when configuring your application later. All right. So next step is to create an environment file. This is where we're going to store a configuration for our application. Create an environment file in your folder. You can do this inside Visual Studio. That's what I'll do. I'll just right click here in this project folder and create new file and dot env is the name of this file you need to create. And in here we're going to have an octa client ID. And that's going to be the client ID value that you just copied out of the octa application that you created. So we need that value and we also need an octa org URL. Where you find your octa org URL is go back to the octa developer dashboard. Click on dashboard up here to take you to the dashboard home page. And your org URL is in near the top on the right hand side of the page. So just highlight that and copy it and go back to Visual Studio code or whatever your editor you're using and paste that in. Those are the two values. Your values are going to be different from mine of course, but paste in your client ID and your org URL. Now next we're going to build our client application. So in the root of your project create a new folder named client and inside client create a new file named index dot html. And then I'm going to copy and paste in a bunch of, well not a whole lot of HTML, but a fair amount of HTML from the blog post that we're kind of following along with this tutorial. So just to walk through what's in this HTML, it's got a doc type, an HTML, a head, a title for this page, which is secure netlify demo. And then we've got a heading header tag and then we've got a couple of buttons defined here, a public button and a secure button that just have labels of test public API test secure API. We will wire these up later in our JavaScript code. Same with the sign out button, which right now has a style of visibility hidden, so this sign out button will be hidden by default when the page loads. We have an empty div tag with an ID of results. This is where we'll add messages and things as part of the output of our application. And then we have an empty widget container div tag, which we'll use to render the login form for the octa login. And then we have a reference to an index dot js file. So inside this client folder, I want you to create a file named site dot CSS. And we're just going to put in some very basic style in here is basically going to copy and paste some code. This is just setting the default font for our web page to use aerial Helvetica set some margins and some padding is just really, really basic CSS styling just so that it doesn't look quite as terrible. And then the big one is we need an index dot js file. So create an index dot js, and then I'm going to copy in quite a bit of code. And then we'll walk through it. All right. So at the top of this, I want to save this index dot HTML file forgot to do that at the top of the index dot js file, we have our import statements. So we're importing in Axios, the octa sign in widget, the octa sign in CSS file and our own site dot CSS file. And then we've got a couple of constants, a org URL and a client ID. Now you need to change these values to match your client ID and org URL. So even though we added these to our environment file, we still need to change also put these into the JavaScript file. So I'm going to go over here to the environment file, copy the client ID, paste that here, and then also copy and paste the org URL. And now let's continue through this JavaScript and explain what's going on here. There are comments all in the code that explain kind of each of the steps and what these functions do, but we'll walk through it together. So we have a display message function that takes in any arbitrary text and displays that result div tag that's in the HTML file. We have a welcome message and that also enables the sign out button. So we have an update this update profile function that takes in an ID token. I'll explain tokens in a little bit, but we're going to enable that sign out button, set the visibility to visit visible, and then display a message that, hey, or hello, meet your name and your email, which are going to be part of that token. And then we have a sign out function that takes in the sign in widget as a argument. And it's going to call some methods or some functions on that sign out widget to clear out any tokens and to sign out the current session. And then it calls window.relocation.reload to just refresh the page. We have a register events function that also takes in the sign in widget. This is an async function, so we probably have some await commands in here. So in this register button events, we are registering the click events for each of the buttons that are on the page. So there's a public button for adding an event listener, which is a click event. And inside that click event, we're going to fetch from our API, our serverless functions API, a function called public test, and then display the results of that response in the browser using the data that's returned from that API. And if there's an error, we catch that error and also show that error message in the browser. We also have the secure route. It looks pretty much identical to the public one, except we're going to use our access token to make that API call. This is how you make a secure API call with Axios or some of the other types of APIs. And that is to set an authorization header on that API call using the bearer syntax. So we've got a header property with authorization, which is equal to bearer space and then the access token, which to us looks like a long string of gibberish, but to a computer, the access token is something that it can parse and verify and extract information out of. It's not encrypted, but it's kind of like it's opaque to us as humans. Computers can interpret it, though. And then we have our sign out button that just calls our sign out function. We have a function called show sign in that's going to render the sign in widget with things like our octa client ID and properties like the redirect URI so that it knows to redirect back to our local host application. And it sets a number of properties and sets a scope. We want open ID and profile and email scopes are like, you know, these are the things I want you to include with the response back from logging in. These are all parts of the OAuth and open ID connect or open OIDC standards. So, you know, everything that's that octa does is part of a an OAuth standard that's portable across any type of web application that supports OAuth and open ID connect. We have a run octa login function, which takes in that sign in widget, and it's going to see if there is an active session like a session means that a person's logged in. If that session is active, then it's going to check to see if there are tokens in the URL that, you know, what happens is the login form goes out to octa. You know, same similar to if you're if you ever log into something and it's asking you to log into Google or your Gmail account or Facebook, you know, those kinds of things. That's that's kind of like an OAuth login where it goes and logs you into this other service provider and then redirects you back to the application with your with your keys or your tokens. So that you can use the application. And that's what's happening here is that when you sign in with the octa sign in widget, it goes and logs you in to your octa account and then redirects you back to the application with some information in the URL is like query string parameters. And so we can pull the that information out of the URL and be able to complete that OAuth exchange by adding those tokens to our our application. All right. So we parse those tokens from URL, which completes that OAuth OIDC cycle. And we store the ID token and the access token in our local token manager. The ID token or the access token is the one that's important for security. This is your this is your like your hotel key, right? It gives you access, you know, here's a card, here's a token. Now give me access to the room that I'm supposed to have access to, or in this case, here's my access token. Give me access to the API that I that I should have access to the ID token is similar, but it also provides information about who the person is that log that is currently logged in. There are things like that person's name, the email address, depending on what claims, as we talked about before, were specified during the open ID that connect call to log in. And then, so if we, after we make sure that we've processed any redirect, and we have our tokens stored, then we're going to get our ID token and update the profile information. One thing to note is that even, even though we may have an active session, perhaps you've logged in to your Octa account and looked at the dashboard, you may have an, you know, an active session, but you may not have what this application is looking for. And that part of what it's looking for is an ID token. And if it doesn't have an ID token, then it can still show the sign in form so that you can log in again and get the correct data that this application needs. And then finally, we have a document loaded event that we're listening to. It's kind of like your, this is how we know that the web page is finished loading and rendering and we're ready to kick off our JavaScript code to do all the things that were listed above. So we're going to create the sign in widget and use like our Octa or URL. And we're saying if we're going to turn on registration for this widget so that if someone doesn't already have an Octa account as part of your application, they can register themselves, you know, fill out profile information and get that, that email verification and all those kinds of standard steps that go along with. Providing a good web application experience. And then we wire up our buttons and run the login experience. All right, so that's that's a whole lot of JavaScript code that we've that we've gone through and I hope the comments and everything are, you know, help to explain what each of those steps are doing. And now this project is using what some people would refer to as vanilla JavaScript or plain JavaScript. We could have used a framework like React or Angular or view to do all these same things. So instead of registering those button click events, we could rely on a framework like React or view to do those things for us. Or even use something like jQuery, whatever tool you're most comfortable with, feel free to, you know, refactor this code to you to work with your tool of choice. I will say that if you use a popular framework like React or view or Angular, we have Octa specific components that are available for those frameworks that you can plug in and, you know, make your life even, even easier. The main thing to understand is that from this front end code is that you're using the Octa sign in widget to log in and receive an OAuth access token. And an open ID connect token, the OIDC ID token. And the access token is the key that allows you as the person logged in to access a secure resource such as an API. And that's what gives you authorization to do that. The ID token includes information about your identity of the person that is logged in, such as name and email address. All right, as I mentioned before, under the hood, Netlify functions are AWS lambdas. And Netlify makes it so much easier to create and deploy and maintain these Lambda functions. One thing you need to know about serverless is the serverless functions are entirely self-contained and independent of one another and independent of the rest of the code that may be in your project. That means if your function has any dependencies, you have to install those dependencies separately from the main project. You package as part of the process of deploying, you have to package up those dependencies during the build process and deploy them with the function, the function code. So the first step to doing this, starting our serverless side of the project is to install the Netlify CLI tool. So let's go back to the command line. And there's two approaches. The Netlify documentation will tell you that you want to install the Netlify CLI tool as a global package, meaning you can call Netlify CLI anywhere on your system at any time. I tend, I'm of the opinion that you should limit how many global modules you have installed on your system, if at all possible. And with the latest versions of Node, it makes it possible to use a global type utility without installing it globally. Now, if you're comfortable with installing something globally, then you do that by typing npm install-g, which is the global argument, Netlify CLI, and that would do the trick. Now you can call that function anywhere. But instead, I am going to install this as a developer dependency to this, this particular project. And this one, this one's going to take a while. There's a lot in this utility, this command line utility. So I may speed up this process, but I will definitely take another sip of a hot caffeinated beverage, beverage, beverage. It is done. And so I can call this function, or you can call this function without having to install it globally, using a cool new utility that's included with Node called MPX. And MPX is like a Node package executor, I guess is what the X stands for, that allows you to execute any module anywhere at any time. But if that module is installed as a dependency locally to the project folder that you're in, it's going to use the one that's already installed, which is going to save a whole lot of time. So we're not going to run this command yet, I'm just telling you what's ahead. All right, so the next thing we need to do is add some configuration to our project that the Netlify CLI tool is going to use. It's going to use this to create the functions and when building and deploying the application locally and building and deploying that application. It to production in Netlify, Netlify hosting. So in the root of your project, create a new file named Netlify.toml or Toml. I guess you pronounce these as Toml files. I'm not even sure what Toml stands for, some kind of markup. But anyway, and then switch over to Visual Studio Code, open up that Netlify Toml file, and I'm going to paste in some configuration here. So we have three major sections of configuration. There's a build, a dev, and a redirects. So the build section specifies the commands and configuration for building and deploying the Netlify application. So the command to build, which is npm run build, we define that in the package JSON file. We're telling it that any Netlify functions are going to be found in a source folder under functions. We're specifying that our node environment is version 12 and that our publish folder is what we want to publish when we deploy the application is going to be a folder named dist, our distribution folder. For development environment things, we're specifying that the port we're going to use is 8080. Again, the publish folder is the dist folder and the command to run our development environment is npm run dev, which we also define in the package JSON file. And then finally, we have a redirects block that is telling Netlify. When Netlify builds and deployed Netlify functions by default, they are at this path slash dot Netlify slash functions. And you know, that works, but it's kind of kind of ugly. But, you know, thankfully, we've got a way using these redirects to use whatever path we want. So if we want a path, be able to call localhost colon 8080 slash api slash whatever name of our serverless function is, we can do that. And it's going to map that call from API to the actual underlying path, which is dot Netlify slash functions. And that's what we need. So the next thing we're going to do is use the Netlify command, the Netlify CLI tool to create the functions that we want. So I'm going to use MPX Netlify functions create specify a name of public dash test. All right. And I get a warning or an error message that the functions folder specified in the Netlify Toml file is not found. So we were looking it's looking for this source slash functions, which we haven't created. So I can either use the command line to make that those directories here, or I can switch over to visual studio code and make those folders here. So I'll say source and create a folder underneath source called functions. All right. Now let's go back and try running that command again. This time we get further. It's asking us to pick a template. What kind of serverless function do we want to create? And there's, you know, lots of examples that we can choose from as kind of like a starting point. In this case, let's just choose Hello World, a basic Hello World function serverless function. It's now been created. If we go back to our project, we'll see that we have a public test folder and under public test, we have a public test.js file. And this has all of our the basic JavaScript code. Now ESLint is complaining about a number of things because it's not formatted the way that I would normally want to see things formatted. If I just resave that file and it's going to clean some of that up. All right. So that's the that's the public one. We also want to create a secure serverless function. So let's use the same command and we'll name this one Secure-test. Again, choose Hello World. And before we go any further, as I mentioned before, if a serverless function has needs a dependency of any kind, that has to be set up, installed separately or copied into that project folder separately. Because serverless functions are independent from everything else, including other serverless functions. In our Secure-test function, we need to be able to verify the access token that's being passed to know if the person who is requesting that API is if that token is valid and if that person is authorized. And we're going to use a tool to help us call the JWT Verifier. So from the command line, change to the source functions Secure-test folder and use MPM to first initialize that folder. So we get our package JSON file and then use MPM install to install Octa JWT Verifier version one. Now we need to update our project with some code. So in the functions Secure-test, open up that Secure-test folder and open up the Secure-test.javascript file. Right now it's just the Hello World JavaScript code. I'm going to delete all of that and paste in a code from the blog post that we're following along with. So this code, and it's complaining about some things. I'm going to go back, excuse me, and in the ESLint rc.js file that we created to begin with, I'm going to change this back to node instead of browser. That'll just make me feel better. In our Secure-test JavaScript file, we'll walk through this. We're requiring in our Octa JWT Verifier module that we installed as a dependency. We have a function called verified token. Verified token, it's an async function that takes in the off header from the request that's coming in to the API. And it splits that off header on a space. So if you remember the standard syntax for passing a token to any HTTP resource like an API is to use that bearer syntax. So it's like your off headers are equal to bearer space and then the token. So what we expect is that when we split that header on that space that we're going to get two parts. And the first part is going to be equal to bearer and the second part is going to be the token. So we expect to have an access token. If there aren't two parts and that first part is not equal to bearer, then we're going to return null, which to our code is going to indicate that someone is trying to access this API and they're not passing any access token at all, which is a no-no, right? Because we want this to be secure. So we're going to take the access token from that second part of the authorization header. And then we're going to use the JWT verifier with our org URL and the client ID. These are being read from the environment. And we're going to call verify access token passing in the access token that was sent as part of the request on the authorization header and this default scope of API default. And if everything went okay, then it returns the parsed JSON web token or JWT. As I mentioned before, access tokens, ID tokens, OAuth, OpenIDC, these tokens are, the format of these tokens are JSON web tokens. And JSON web tokens is just a standard way of packaging up information and they have what's called a cryptographic signature and that signature helps the verifier to know whether or not that token has been tampered with since it was originally issued by the authorization server. So an authorization server, when you log in, it provides that access token, generates that access token and provides it back to your client side code. And if you try to do anything with that token, if you try to insert more data into that token or try to falsify that token, the verifier is going to know that you've tampered with it. Also inside a JWT is things like an expiration date. So JSON web tokens don't live forever. They're relatively short, have relatively short lives and that's another security standard. So if a token is expired, then the verifier is going to reject that token and whoever's using that token won't have access to that resource until they get a new access token. All right, so enough of that. So that was our verify token function. And then the magic for a serverless function is the handler. So the standard syntax for the handler is it is an async function. It takes in an event and a request context, which we're not using the context in this example. But the context can include things about the request, maybe some data that was passed along or whatever. So the JWT, we're going to call verify token passing in the event dot headers dot authorization. So this is like the request that's come in. And if we got nothing back, if the JWT is null, then we know, well, maybe there's there's either a problem with the token or maybe there was no token at all. So we're going to return 401, which is the status code for not authorized. And with the text, you're not authorized to access this resource. But if everything was good, then we're going to return status code of 200, which is the OK status. And with the headers that are the content type that we are returning is application JSON. And the body of our response is going to be a message, a JSON or a JavaScript object with the property of a message that has hello. And then we're passing back a claim that's embedded in that JWT. So the JWT that was parsed, that's the access token, it has some basic information in it. And we can pass that back from the API. Now, normally, I'm not doing this in this tutorial, but you would take that access token and perhaps make additional calls to other APIs or to use that use access token to make calls to an internal service or maybe a database or whatever. That access token can be passed along to make other other calls to other things within your the architecture of your application. So that those things know who that person is that's requesting the information. All right, I think we are now ready to test everything that we've done so far. So let's close all these files and let's open up, go back to our terminal and change back to the root of our project. And let's call npx netlify dev. And this is going to have something else running. Let's try that again. It's going to spin up a local development web server. And it's going to host the netlify functions locally so that we can test those functions locally. It's going to call those build commands such as clearing the distribution folder, calling parcel to package up our HTML and CSS and JavaScript and all that kind of stuff and deploy it. And it now says that the server is ready on localhost 8080 and parcel has built our application. Now before we open up the browser, just wanted to show you, if you go back to Visual Studio Code or if you want to, you know, look at it some other way, you'll see that you now have a folder in the project called dist. And, you know, it, man, it stuck a whole bunch of stuff out here in this folder. That's because it was able to package up all those dependencies, all the files that are associated with those dependencies like the CSS for and resources for the octa sign in widget. And yeah, just tons and tons of stuff that's now part of the our web application that that our application depends on. So that's going to get cleared out every time we we rebuild our our project and, you know, parcels going to create all that stuff worse again. So open up your browser and go to localhost 8080. Now I recommend to get like a true end to end test that you launch a private window private browser instance. So I'm going to do that. I'm going to open up an incognito browser window and go to localhost 8080. One thing to note is Chrome has added, if you're using Chrome, Chrome has added this function or this option down here and it may be turned on by default. But it says block third party cookies. If you turn this on right as as of this recording, it's going to break the octa sign in. So you need to allow third party cookies in order for the session system, the cookies that that octa sets when when you log in to work correctly. So make sure that if you're going to use an incognito window that you have these third party cookies enabled or it's not going to work. All right. So you should see what I'm seeing Netlify function tester. We've got a couple of buttons up here and then we have our sign in username password. And then there's also a link down at the bottom that says if you don't have an account, then you can click sign up. So enter your octa developer account credentials, the same ones that you use to create your your octa developer account. You can also create other logins. You can also use the register function to create a whole new log in if you've got a different email address. And if all goes well, it's going to sign in and you've got, you know, it went very, very fast. But you may notice in the URL that, you know, the URL was full of stuff at one time and now it's not anymore. Those were like the intermediate, intermediary code and temporary tokens and things that the login needed to complete the OAuth and OIDC authorization process. So now we're logged in. We see a new message. Hello. You know, for me, it's hello, David Neil and my email address. And that's pulled out of the ID token. That was part of OIDC. And then we can click test public API and we get a message back. Hello world as we would expect. And that's calling our local functions. And then test secure API. It worked. If everything goes well and, you know, you're signed in, you've got your access token. It can call that secure API endpoint and verify the token and respond back with hello. And one of the claims inside that access token is. It's called SUB that stands for subject. And the subject of that claim or the subject of that access token is you. It's your ID. You're, in this case, email address. And then finally, we have a sign out button. And, you know, we get our form again to log back in. Here's the log in session and we're back to the beginning. Sweet. Everything is working and going to plan. Here's where I would insert a animated GIF. It's working. Yes. Success. I hope you're having success as you're following along this tutorial. So now we've got our application working locally. What do we, what's next? Well, the next step is to set up continuous deployment with Netlify. We want to, we want to deploy this thing into production. And to do that, let's create our Netlify account. If you don't have it already, go to Netlify.com, sign up for your account. But the first step to get this to work like we want it so that every time we make changes to our code, that code gets redeployed through Netlify automatically. We need to put all this code that we've created so far into a Git repository that Netlify can access. So Netlify supports GitHub and GitLab and BitBucket and, you know, maybe some others, which all have free editions of public Git repository hosting. I recommend that you pause this video and follow along the instructions that are provided by your Git host of choice to create a new repository for your project. And maybe, you know, make that first step whatever you're comfortable with and come back. I am going to go to my GitHub account and I'm going to create a new repository. And I'm going to call it Secure Netlify demo, which is available. I'm going to make sure that it's public. Now Netlify will work with private repos too through, you know, your authorization. You can grant it access to view your repository. I'm going to create this repository and, you know, when you create a repository in GitHub, it gives you another number of steps that you can use to initialize your project. So I'm going to follow kind of these steps right here from the command line. So I'm going to come over to here, press Control C to stop my local development server. I'm going to use Git init to initialize an empty Git repository. And one thing that I want to make sure is that not everything that we have in this project is something that we want to commit to our repository, specifically like the .env file. That is environmental specific, configuration specific to like my local development, you know, and it may, you may have some secrets in that file at some point that you don't want to commit to a repository. So I'm going to create a .gitignore file and in Visual Studio Code, I'm going to open up that gitignore and copy and paste in some stuff here. So we don't want to commit our entire node modules folder to source control. That's bad. We want to ignore our .env file and then, you know, just anything else that might show up. We don't want to commit our distribution folder either because that's going to get created and at every time we deploy or Netlify is going to run our deployments on their system to set up the dependencies and everything to deploy your project. Let's see. So back to command line. We ran Git init. Let's add a git remote add origin and then the address for your repository. I'm going to add my repository, paste that in there. And then I'm going to git add everything. If I look at git status, which I always do is kind of like a sanity check. Make sure that nothing that I don't want to deploy is getting deployed. That all looks good. I'm going to commit that as an initial commit as the message. And then I'm going to git push with a dash U. So the first time you push to a new remote, like we set up a remote to your repository, and I'm using my repository, dash U is going to tell git to use that repository or that branch from now on to push things to. So anytime we type git push without any parameters or additional arguments, we're going to push the current branch to production or to the main branch. All right, now that we've got that code deployed or that code committed to the repository, we can go back to repository refresh here. Everything's good. Everything was committed a minute ago. Now go over to Netlify and log into your Netlify account. If you're not already logged in, I'll log in with my GitHub account. And I've already got some other stuff sitting out here, but you want to click new site from git. And as I mentioned before, it supports GitHub, GitLab and BitBucket. I'm going to click on the GitHub button because that's what I'm using. And it's going to, it popped up a separate window to authorize my GitHub account, which I've already done before. So that only took a second and went away. It might take an additional step for you to log in and grant access to Netlify to access your repositories. That in itself is an OAuth flow where you're logging, you're using your credentials with GitHub and you're granting Netlify a specific set of privileges. And it's, you know, under the covers it's using OAuth to create that access token that it's going to use to make API calls to your Git repository. Pretty cool stuff. Anyway, I've got a whole bunch of repositories sitting out here. I don't want to browse through them. So I'm going to say search for secure. And there's my secure Netlify demo that we just created. Going to click on that one. And then let's see what else. One thing we need to do is we need to do a couple of advanced steps. So everything else is fine. It picked up from it. It actually read the Netlify Tommel file from the repository so it knows that the build command is npm run build. And the publish directory is going to be the disk folder. But under advanced is where you define environment variables. So since we are not deploying the .env file, we need to set environment variables for this particular application. So click on new variable. And I'm going to just pop over to Visual Studio Code and open up that environment file. And so we want one called Octa Client ID. So this could change. If you wanted to have a separate Octa application instance for local development and another one for production, this would be different for your environment. Going to create another new variable. It's going to be the Octa or URL. And now we're ready to deploy. So the name of my application is Fervent Turing D1D536. I'll commit that to memory. Yours is going to be different. But the cool thing about Netlify is it creates these kind of placeholder URLs that you can use to view your application. So while it's building, let's see what else we may want to do. When this is done, it's going to generate a URL for this website. And before we can actually test this application, we're going to need to let Octa know this new URL that we're using. So let's see how far along we are. So I think if you click on the Site Deploy in Progress, you can actually see a little more details. You can drill down into and actually see the build process and everything that's been going on. So I think it's done. Mine is. It still says it's in progress. Brevid? What did I say? And there we are. Netlify has deployed our application. I just needed to have a sip of coffee. So here's our URL. We need to let Octa know that we're using this new URL and to permit this new URL as part of the login process. So right click on this link and copy that link address. Now go over to your Octa account and click on Applications. Go to the application that you created for this tutorial. Click on the General tab and you've got all our settings. We've got things like this login and stuff. Click on this Edit button and we need to add some URIs so that Octa knows these are valid. So on the login URI, paste in that new URL and for the logout, do the same. And then we also need to change the initiate log. You don't have to, but I'm going to go ahead and change this initiate login URI. This should be whatever your production site is, not local host. So this is fine. And let's click. All right. Now there's one other thing we have to do with Octa and that is to add this site as a trusted origin. This is the terminology that's used. So Octa knows that if a redirect comes from this site, it's okay, it's expected. So click on, go to the API menu, click on Trusted Origins and here click on Add Origin and we'll give it a name like Netlify Secure Serverless Tutorial. The URL for the app and we want to allow cores and redirect and click Save. So now if we were ready to test, so open up another browser or open up a, let's open up an incognito. Go to that URL. Sweet. We got our buttons and now we got our login showing up here. Let's try logging in. It's working. Test the public API. Now this is calling Netlify functions. This is going off and executing a function that lives somewhere else in the cloud. This is an AWS, a true AWS serverless function. So the public one works, the secure one works and then we can sign out. If we try to call secure API function when we're not logged in, it tells us we're not logged in. We can't use that. We can still hit the public window. Sweet, sweet, sweet. All right, that is it. Oh, except maybe we want to make a change and yeah, we want to see that we can deploy a new version of our application within a minute or two, which is one of the beauties of working with serverless functions. So we're working with Netlify. So let's go make a change to the application. Whoops, don't know what's going on there, but don't save that. Let's go to our functions, maybe the secure test and change the message from hello, whatever this is, to hello, period, it's working. Maybe change something on the home page too. Let's see. So go to the client index.html file. Add another something here called hey y'all. So go back to the command line. We do a get status. We should see two files have been changed. Let's add those two files, commit them to the branch changes for the demo. And then let's push, pushed to the get repository. And now if we go over to our Netlify account, let's see. Maybe go to the deploys tab. Look you there. It is now building a new version of the application and it has the commit message that I put in there, changes for the demo. And if I want to, I can click on that and I can actually watch the deploy happen, which should be about done. It still says it's building. It's probably packaging up those functions. Let's go back and look at that again. So let's run an npm build. It's created all these distribution files all the way down and now it says the site is live. So let's go back to the incognito window that we had open earlier. I'm going to refresh this page. Look you there. Hey y'all. Log in again. Whoops. Helps to type in the correct password. Test our secure API. It's working. Yes. Well, that is it. We've done all the steps, all the things that we've set out to do. I hope that you've enjoyed creating this, learning how to create secure serverless functions using Netlify. As I've said before, Netlify makes deploying applications so easy. Okta makes adding authentication and authorization to your applications so easy than having to do these kinds of things on your own. So again, I'm going to post some links to some resources into the description below. And as always, you don't need permission to be awesome. You get out there. Do stuff that you're learning and you do some awesome things with it. I would love to hear your feedback. If you have any comments or questions, leave those down below. And until next time, hope you have a blessed day. See ya.