Firebase Functions Authentication - The Diligent Dev

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what is going on everybody it is rob aka the diligent dev and a few months ago i created a video going over firebase functions and in particular how to create a rest api using them and since then that video has gotten a decent amount of views and i've gotten a lot of questions out of it and one of those questions was how to implement authentication so in this video we're going to go through our firebase functions rest api and we're going to be using some authentication middleware so that we can lock down our api endpoint so people can't manipulate data maliciously so let's jump over the computer and get right into it okay so here we are over the computer and since this video is going to build on top of another video i did creating a rest api with firebase functions we're just going to go ahead and clone that repository if you haven't watched that video and you're interested in watching it i will link it on the screen right now and i will also link the url to this bitbucket repo so here we are over the bitbucket repo i'm just going to go up to this clone button i'm going to copy this out i'm going to open up a new terminal i'm going to cd into my desktop directory and then i'm just going to go ahead and paste that git clone in there and it's going to go ahead and clone our project so now that it's cloned we might as well open it up so i'm going to open visual studio click on open go to my desktop and find our firebase functions api now that we're in here i'm going to go ahead and edit some files here we're actually going to delete some out because i'm going to come at it from the standpoint of the viewer of you guys and you're going to be initializing firebase in here and it won't initialize it if we already have some of these firebase files in here so what we're going to do is we're going to delete this firebase rc file so go ahead and delete that might as well delete the firebase.json our firestore rules and our firestore index i'll go ahead and close these out i'll just update later and then we're going to head over to firebase and go ahead and set up a new project so we'll click go to console up here i'm going to click add a project and we'll say firebase api off go ahead and hit continue i'm not going to enable google google analytics for this project and i'll create the project and once it's done creating our project i will be right back and now that our project's been created we're going to go ahead and enable some things the first thing is going to be authentication so we're going to click on authentication we're going to go to sign in methods we're going to click on email and password and i'm just going to go ahead and enable this top toggle and save it and we see that email and password is now enabled next we're going to do is go to cloud firestore and up at the top here we're just going to click create database we're going to start it in test mode now if you've watched any of my other videos you're not going to want to do this in a production application if you're going to put out a production application make sure you familiarize yourself with firestore rules because this is going to allow anybody to read and write to this database but we're going to do it for now we're going to click next and we're going to click enable and once it's done provisioning cloud firestore i will be right back and now that our firestore's been provisioned what we need to do is install the firebase cli if you don't already have it installed so i'm going to do is just open up a new terminal i'll just clear this out and we're going to run the following command npm i g for global firebase dash tools now if you're on a mac you might have to put sudo in front of this and enter in your password since you're installing this globally but on the windows machine you won't have to do that now i already have this installed on my machine so i'm not going to run this command but what i am going to run and what you should run after you've installed the cli is firebase login and what this will do is it will prompt you to log into your account it'll launch a new browser window and you can just go ahead and log into it like you log into any google account you'll see that i'm already logged in as thediligentdev at gmail.com but you're going to be prompted to log in under your account and what this is going to do is it's going to sync the cli up with the firebase tools so that when we provision stuff using the firebase cli it knows which account to use and now that we have everything set up and ready to go what i'm going to do is open up visual studio which we have our firebase rest api project opened in and i'm going to open a new terminal and what this is doing is just ensuring that i'm in the root of the project and we're going to run the following command firebase init it's going to ask us which firebase features we want to use in our project and all we're going to do is come down to functions hit space to select it and then hit enter it's going to ask us if we want to use an existing project or create a new one and we're just going to use an existing one and then what we're going to do is select that project that we created earlier so i'm going to go down here and hit enter it's going to ask us which language we'll just say javascript we will say yes to install eslint or use it it's going to ask us you know if we want to overwrite all of these files that are already in here and this is part of the reason that we deleted a lot of those firebase files when we first started was because the firebase cli will not initialize because it'll already think that a project has been initialized in here so it's going to ask us if we want to re overwrite all these files that already exist and we're going to say no because we want to keep those files but we just want to point the cli to use the existing project that we created if that makes sense so i'm going to hit no we'll also hit no here we're going to hit no for the get ignore do we want to install dependencies we will say yes and now firebase is all set up so it's going to be using our existing firebase functions but it's going to be referencing your account so that you could push these to your account and use them instead of referencing my account okay now that that's all set up and done let's go ahead and look at our rest api and do a little recap of exactly what we did so you'll see that we have our firebase functions import we also import express we import the firebase admin because we're going to be accessing the firestore we create an instance of express that we set to our app and then we start defining our express routes now see we have a forward slash and this is to get all users so we grab the user's collection we loop through all the documents put them into an array and then pass them back with a status of 200. now if we want to get a single user we would pass an id we would go look for that user in the database and grab them and then pass them back we have a post and this is for creating a user so what we did here is we created a user based on the request body that we passed in we referenced the collection of users and added that user and passed back a status of 201 which stands for created we also have a put and this is for updating users so we would pass in our updates in the request body we would go grab that user from the id we passed in the url parameter and then we'd update the user and send back a 200 and then for deletion we would pass in an id then we would go to the users collection find the document that id and delete it and return a 200. now this is all great and everything works fine but unfortunately we don't have authentication on here so anybody can go sniff our endpoints by opening up like chrome dev tools and looking at the network tab and they can go in here and potentially manipulate data so what we want to do is lock it down and just like any other firebase product the firebase team has made this extremely easy for us to do so if we go and we look at their documentation for their sdks you'll see that we can grab something called an id token on the client so we on the web we call something like firebase auth current user get id token and it's going to give us the id token which is essentially a json web token that we can pass to our back end and verify it so if we go down and look at what we would use on our back end you'll see they have admin auth verify id token and if it resolves correctly then we'll drop that into the then block or if it errors out we can handle that error and say that essentially no one's authenticated and we can see that they have a bunch of different sdks that you can use in your backend we could be using java python go or c sharp and on the front end they have the web c plus plus unity android and ios but for the front end i'm going to make this language agnostic and framework agnostic so what we're going to use is the firebase authentication rest api so if we go ahead and we look at their documentation and we scroll down a little bit here we see that we have this url that we can call our rest api endpoint and we pass it an api key that we're gonna go grab from our firebase console and then we pass it a request body payload of an email and a password and then it's gonna return us this secure token which is our json web token so we're gonna need to do is go to the console go back to our project click on this little gear icon go to project settings and we're going to copy this web api key and then what i'm going to be using to create my user or sign a user up is postman and i will leave a link to this in the description and i'll leave links for all these firebase urls in the description as well and i'll just grab the firebase console and we will stick it over here and then i will stick the postman over here i'm going to go ahead and open up a new request and i'm actually going to head back to the rest api firebase auth rest api and we'll scroll down to that call i'm just going to go ahead and copy it out of here and we're going to paste it in here and then for this api key you'll see it down here in our params we can go back to the firebase console we'll copy that and we will stick it in there the next thing we're going to do is pass our request body so we're actually going to make this a post request we will go to body i will click on raw and then we'll go to json inside of curly braces we will say email the diligent dev gmail.com we have to also pass it a password and we'll just say password one two three and then we will pass it return secure token and i gotta wrap this in quotes and we will set this to true now that's all set up all i have to do is hit send and we see we get a response back from the rest api and we get this id token right here so if i head over to jwt dot io and we validate this web token i'm just going to go ahead and grab it and paste it in here we see we get all sorts of information in here we get the user id which is right here that's also the sub we also get their email tells us if their email is verified we also get some claims but i'm not going to go into that for this tutorial as it might get too complex but you see we had a lot of information here that we can access out of this token and now that we have this token to pass to the back end what we can do is we can authenticate our rest api so what i'm going to do is i'm just going to minimize postman for now now since we're using express for our rest api we can tap into something called middleware now think of middleware as a function that fires between the request and the response of our api and we can intercept things in between that request and response before it actually hits our endpoints so what i'm going to do is i'm going to come to the functions folder i'm going to create a new file and i'm going to call it auth middleware dot js and this is where our authentication middleware is going to live now fortunately for us the firebase team has a github repo and it has a ton of sample functions in it and one of the sample functions is authorizing https endpoints so if we scroll down here a little bit we see we have this function called validate firebase id token and it's doing a lot of stuff but all we have to do is what i'm just going to copy everything inside of this function and we're going to paste it into our off middleware.js and before we edit anything in this file let's just go through it and see exactly what this method is doing so it's going to go ahead and console.log to say that it's requesting an authorization with firebase id token and these logs are kept inside of the firebase console if you click on your functions tab and go look at the logs for each individual function you'll go ahead and see your function logs so what it's doing is checking to see that there's an authorization header and that it starts with bear and it's checking some cookies as well and if we don't have those then it's going to console log and error and return a 403 which stands for unauthorized and then exit the function when it gets down to this point it sets an id token we're checking the authorization header exists again and then it starts with bear and if it if it does then we're going to console log that it found it and all bearer tokens start with the word bear so it's going ahead and splitting the token and then taking everything after the word bearer it also checks to see if it found a session cookie and if the cookie contains the id token if none of those are true then it's going to drop down into this else block and it's going to return a 403 unauthorized once it gets down to this block it's going to try to decode the token and if it decoded it successfully it's going to log it and set the user equal to the decoded token and return next which essentially allows it to continue on to our api endpoint if it does not decode the token successfully then it's going to return a 403 unauthorized now the way this file stands we can't exactly use it we have to add a few things and modify so what we're going to do is we're going to say const admin here at the top equals require firebase admin and then so we can import this and use it in other files we're just going to remove cons and we're going to say module dot exports and set that equal to the validate firebase token id and go ahead and save everything then we're going to head back to our index.js and right here we're going to go ahead and import our middleware so i'm going to say const off middleware equals require and then the path to our off middleware now there's a couple different ways we can use the off middleware we can either apply it to all routes or just a specific route if we want to apply it to all routes we'll just say app.use and then pass it the off middleware in the event that you didn't want to lock down every single route that you have we'll just go ahead and comment this out we can use it like this we can put it right after our route we can say off middleware and this will only apply this off middleware to this exact api endpoint but for now let's go ahead and get rid of this and let's apply it to all routes i'm going to hit save then i'm going to come down here to the terminal and i'm going to run firebase deploy dash dash only functions and once the functions get deployed i will be right back okay now that our firebase function has deployed what i've done is i've opened up the firebase rest auth api and we see we have an endpoint here to sign in with email and password and we have our postman application open over here so i'm going to do is copy this and paste it into postman you'll see that this is a post method so we will change this to post we need our api key which we used earlier so i'm going to go ahead and go to params and copy that out we need to pass it an email password and the return secure token so i'm going to go to body raw json i'm going to come back to this i'm going to look at the body that i passed in because it should be the exact same and i'm going to paste that in there and then i'm just going to hit send and you'll see we get a good response back there's a lot of information in here but the thing that we're concerned about is this id token so what i'm going to do is i'm going to copy this i'm going to open up another tab and this is where we're going to make our request to our firebase function so the first thing we need is our authorization it needs to be a bearer token so i clicked on authorization we'll go down and select bearer token and then i'll take that token that i took from our last request and paste it in there we will come over to our firebase console for our project and we will go to not cloud firestore but functions and we see we have our function in here so i'm going to go ahead and make this just a little bit bigger so i can copy the url for that function out of here and what i'm going to do is i'm going to make a request to this endpoint and we see we didn't get anything back because i don't have any users in there any longer this was a function that returned an array of users we just have an empty array but we did get a 200 back so if we take this off and say no off we see we get unauthorized if i go back to bearer token luckily postman does keep this cached so if i go ahead and delete just one letter off of this it should invalidate the token and that is completely correct so if i add that e back on and hit send we see we get our empty array back so our authentication middleware is working and if we head over to our function logs we can see all the different logs that are being called inside of our off middleware so we can see that the one time we didn't use it and we logged an error and then when we edited the token it also aired out but you can see that on a lot of the requests it did find the authorization tokens now i know we use the firebase rest api to generate our tokens because like i said earlier i wanted to make this language and framework agnostic but they offer a bunch of different sdks and we'll go ahead and just briefly look at the javascript one in order to create a user they have this function once you import the sdk into your project called firebase auth create user with email and password and then to go ahead and sign in your user they have a very similar function with sign in user now in order to get the id tokens you would just call once your user is logged in you call firebase.auth.currentuser.getidtoken and it'll return you that id token and then we've already talked about how you verify that on the server and there are tons of different sdks i'm just looking at web but they have ios android web c plus plus unity and unity and then of course their admin library but that's going to go ahead and wrap it up for this tutorial i hope you got some value out of it and if you did make sure you hit that like and subscribe button and until next time happy coding
Info
Channel: Diligent Dev
Views: 9,666
Rating: undefined out of 5
Keywords: firebase functions, firebase functions node js, firebase functions firestore, firebase functions express, firebase functions javascript, firebase functions rest api, firebase functions authentication, firebase cloud functions auth
Id: hkxyt8FImcM
Channel Id: undefined
Length: 20min 35sec (1235 seconds)
Published: Thu Aug 27 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.