Next.js and Django JWT Authentication | Part 1 - Backend API

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
have you ever wanted to know how to implement a fully featured authentication system using Json web tokens account activation password reset and social login well we're going to cover all of that in this series not just that you're going to develop this application through the series you're also going to be deploying it so that you can see how a deployment works with this type of application and you'll even see how to configure a custom domain as well just like you can see up here the deployment itself will be doing on digitalocean and will use things like digitaloceans domain management to help set up our custom domains we use the digitalocean app platform to help with easily deploying our backend and front end and we'll be using digital ocean spaces as a static file storage service and then we'll also be using AWS simple email service to help with sending emails in our application so here inside of digital ocean this is kind of like the setup just so that you can see what we're ultimately going to end up getting to so I've got the custom domain I have digital ocean spaces holding the static files and then also with app platform I have the backend deployed as well as the front end and then the front end is on this domain and then the back end is on this sub domain so that's kind of the setup that we're ultimately gonna get to to implement this app itself we'll be using Django with Django rest framework for the back end API and Django rest framework in case you don't know is a library that gives Django more features to help with putting together rest API endpoints very easily and then for a database we'll use SQL like 3 when we're on our development environment and then we'll use postgres when we're in our production environment and then for static file storage we'll handle this differently in development and production so during development we'll handle it more like the standard way you do with Django and then in production we'll have our static files stored in the digital ocean spaces also just something to note for this particular app setting up the static file storage and this way is pretty Overkill since there will barely be any static files in this particular app but the reason I implemented this way is just so that you can see how you can do this sort of setup and then also because realistically you'll never have an app that does just authentication and that's it typically an app that has authentication will have tons of other features built on top of it as well for example you might have a social media app and then you can have users that store all kinds of posts and images and then in that kind of case a solution for static file storage like I have implemented here would be a lot more effective so just wanted to put that out there just so that it's clear why we're doing things the way that we do them in this app and then other things to note with the back end we'll be setting up a custom user model and then that way users can register and log in using an email and password we'll be using the joser library to help us quickly put together a fully featured authentication backhand API and then you'll also see how to easily overwrite certain behaviors in a library and then that way you can get it to do something specific to what you want in your particular use case in your app and then what we're going to be overriding in particular in our app is how the Json web token authentication endpoints behave as well as how the authorization behaves so by default the way that things will behave is that when you hit an endpoint to create your Json web token credentials you'll get back in the response data your access and refresh tokens and then you'll also need to store them somewhere then to make authorized requests you'll have to pass an authorization header and then you're going to have your access token in there of the value in that header we'll be changing this Behavior so that instead the access and refresh tokens get stored in cookies with the HTTP only flag accepted true so that way client-side JavaScript won't be able to read the values of these credentials and they're going to be stored in a very secure way as a result and then we're also going to see how we can override the authorization so that you don't need to pass an authorization header but instead you'll just have the access token which is in a cookie and then you'll just extract that value and use that to make the authorizer quest then we're also going to see how to implement social authentication with this app and we're going to be using Google and Facebook oauth 2 in order to implement this now for the front end to build out the front end we'll be using next gs13 with the app router we'll be using Tailwind CSS for The Styling along with things like headless UI we'll also be using Redux toolkit for our Global State Management for the authentication and rtk query for our client-side requests and then these will be the authentication requests because that's the only feature we really have in this app so you'll see how to configure this setup with nextges 13's app router then another thing that will set up with rtk query is automatic reauthorization so this means that anytime we hit an API endpoint where we're unauthorized to make the request which will frequently happen because we'll have access tokens that expire after five minutes what will happen in this case is that when we get this unauthorized response we'll automatically in our app hit a refresh endpoint using the refresh token that's stored in our cookies we'll get back a new access token and then we'll retry the unauthorized request with the new access token which will now be valid and so the request will work during the retry now I just want to point out that in this particular app with this setup we won't be taking advantage of certain things in next js13 such as the server-side data fetching so our app will instead be doing client-side data fetching and caching with rtk query So currently with rtk query we can only make client-side requests with these server components and that's why we're doing that in our particular app however in an app that builds on top of having authentication you would technically have many features that could take advantage of things like server-side data fetching so for example an e-commerce app is something that you could build on top of this authentication system and that will have things like product data which is a great use case for things like server-side data fetching of the products and then when they're on like a shop page or product detail page in that case you could take advantage of these sorts of things but in our app since we're using rtk query with the automatic reauthorization setup for our authentication endpoints we'll only be doing client-side data fetching so that's just something I wanted to put out there anyway that is an overview of what we'll be going over in this series and next I'll go over the actual app itself and as you can see on the screen this is an app that is running in a production environment on digitalocean with our digital ocean setup right over here but before I get into the overview of the app make sure to hit that like button on the video if you haven't done so already helps the YouTube algorithm so that more people can find this kind of content also hit that subscribe button if you want to see more content like this and hit that notification Bell if you want to be notified when I release new videos and with that let's get into the overview so here we can see this is the home page styled with Tailwind CSS we have our nav bar we have our footer and then we have our login and create an account buttons that we can click so I can go to create an account that will bring me to the sign up page so let's go ahead and sign up for an account so I'll sign up with a John Doe accounts [Music] there we go we put in the credentials and then you can also sign up with Google and Facebook but first I'll show this so I'll click the sign up button now we're also going to have alerts in this app so these will be handled with react toastify so here we can see an alert for please check email to verify account so I can now go into my email then if I refresh I should receive an email so this one ended up going in the promotions tab so let's make sure it's over here I'll click on this and now I get a link so I see you're receiving this email because you need to finish the activation process on full auth which is the name of our app and then please go to the following page to activate the account so I can just click on this and there we go account activated just like that so now I can log in with this account and there we go we're logged in and now we see we're on a dashboard page we also see our nav bar was updated so now we have a dashboard and a log out button so I can see I have the first name John last name last name doe email so all of the things that I signed up with on this account I can go back to the home page dashboard log out I can refresh the page I'm still logged in so in this particular case we use things like our verify route in order to make sure that we have a valid access token and if we end up being unauthorized because let's say more than five minutes passes so our access token expires when we refresh the page we're going to get a 401 response so we're gonna go hit the refresh endpoint automatically get back a new access token and retry the verify routes which will then succeed and keep us logged in I can also open up the console along with the application and then here I'm gonna have to log out and then re-log in just so that we can see the access and refresh tokens here so if I log out go to login and then I log in so I'm going to see that the access token is here along with the refresh token and then we can see some other properties on this as well so we can see that the domain is set up The Path when it expires the HTTP only flag which is an important one so these cookies here they cannot be accessed with client-side JavaScript because of this setting here they also have to be secure so they need an https connection and then we also have same site as none and this is because our front end and our back end are on different domains our front end is on this domain and then they back in this on a sub domain so we're also going to see how to do that setup so that this works properly and the cookies get sent in the requests and yeah so now back in the app if I'm on the dashboard page I click log out I'll get navigated to the sign in page so now the next thing I'm going to show is the forgot password click on this I can put in my email [Music] and then I'm going to request a password reset so request sent check your email for reset link so I can go back I'll get a new email password reset on full auth so now I can click on this link and then here I'm prompted to put in a new password so let's go ahead and do that and then it seems that I didn't have these passwords match this is also a great thing it shows what happens if the passwords don't match it won't end up working now if they do match there we go password reset successful so now I'm going to try to log in with the old password and if I try to log in with the old password I should not be able to log in so there we go failed to log in so now if I put in my new password and sign in with that there we go it works so that is the password reset and then only one more thing to Showcase in this app and that is the Google sign in and Facebook sign in so if I click on the Google sign in here's the Google sign in page I can click on this account and there we go I'm logged in with that account and then the final thing to Showcase will be the Facebook oauth 2. so if I click on this button instead there we go I'm logged in and I can also see that the first name and last name is slightly different than the other account because these are the details on the Facebook account for this email so you can see that now we have an email and a password login we have account activation we have password reset and we have social authentication with Google and Facebook oauth 2. so that is the complete overview for this particular app and now what I'm going to do is in the first video I'm just going to go over the whole setup for just the backhand API so that's going to be with Django and then the second part in the series is going to be just the next JS setup so that way if you're interested in just Satan xjs then you can just go to the second part of the series and then you'll just have to configure the backend API so that it works on your local system and then from there you can just see how you can implement this sort of authentication system on the front end with nextgs app router if you're interested in just the backend API I'm going to cover that in this video and if you're interested in both then you can go through both parts of the series so with that let's now jump in and see how we can put together this Django back end all right now let's see how we can build out this Django backend API for this project so right now I have vs code open which will be my text editor of choice and then I have a folder open called Full auth API and then this right now is sitting inside of a full auth folder so I'm going to have my backend API with Django and I'm also going to have my next GS project in here as well just to organize things so before I get started I'm just going to show some of the vs code extensions I'm using so I have this Auto rename tag which is pretty handy this one's more handy for when we get to the next GS stuff I also have Auto Pep 8 as the python formatter and then there's this Django extension which is more useful for when you're working with templates dot EnV just for some syntax highlighting with DOT EnV files and then we also have this react Redux Snippets extension so this one you get these little commands you can put in and then click Tab and then it'll just auto-generate some stuff now personally I don't really use this one that much but it is a useful one I would just have to get used to some of the shortcuts and then we also have prettier which is the code formatter that I use except with python I'll be using Auto Pep 8 instead then we also have this pylance and python extension and then we also have Tailwind so that's going to be something once we get to the next GS part so those are my extensions so the next thing I'm going to do is open up a terminal so the version of python that I'm using right now is 3.11.3 and then I'm going to set up a virtual environment so I can do that with python3 Dash M then v e and V and then v e and V so this is the command this is the name of the folder I'm going to have the virtual environment and this way I can have my python packages installed in a virtual environment instead of on my global system and then the next I'm going to do is activate this virtual environment with source that have been activated and if you're on Windows this will look something like dot backslash them back scripts backslash activate.bat although one thing I do recommend if you are on Windows is you can also set up Windows subsystem for Linux that way can have an Ubuntu environment on your Windows system then there's some extensions you can have in vs code to work with that so then he would just go here and then he could connect here WS cell environment and then that way you can use the Ubuntu terminal which you'd be using bash instead of using the command line with Windows and it's just a nicer way to develop when you're on Windows so the next thing I'm going to do is install some packages I need so I can do that using pip install and then also right now inside of my virtual environment by the way if I do python version right now I don't have to use Python 3 because the default version of python in my virtual environment is already this same with Pip so I don't have to do things like pip 3 install I can just use pip install so one thing I'm going to need is Django rest framework and Django rest framework has a dependency of Django so I don't have to specify Django here as well I can just install Django s framework and that will behind the scenes installed Django as well also going to need Joe sir this is going to be my library for managing authentication in this project and then another thing I'm going to need is Django cores headers so we're going to need course headers in this project because our backend API and our front end is going to be on separate ports and also separate domains so in particular when we're in a development environment it'll be separate ports because the backend will be on low cost 8000 the front end will be low cost 3000 and then because we're gonna have authentication and we're going to be using cookies we're going to need course headers in order to allow cross-origin requests to happen and then in a production environment we're also going to have different domains because our backend API is going to be on a sub domain so it's going to be like API dot whatever the domain is.com let's say and then the front end will just be thedomain.com so it'll be different domains so we're also going to need to set up course headers to allow those cross-origin requests and then the last thing I'm going to install for now is python dot EnV this way we can have a DOT EnV file where we can have environment variables so all of those installed now so I'm gonna clear and now if I do a pip freeze so these are now all the packages that we have and this is in the virtual environment so now what I'm going to do is I'm going to create a requirements.txt file which is going to have all of those dependencies so I'm going to do pick freeze then it's greater than sign and requirements Dot txt so now inside of here I have all of those dependencies right here the next thing I'm going to do is generate the Django project so I can do that with Django Dash admin start project I'm going to call this full underscore auth I'm going to put a dot so that gets made in the current directory and then I don't have full auth and then another full auth folder so I'll show you what I mean so if I don't put that dot inside of here I'd have another full auth folder and that would have all of this inside there so I didn't want that so that's why we put this for the current directories where I want to have this project present so the next I'm going to do is I'm going to create the app so I'm gonna have only one app and that's going to be a user's app which is going to be for managing users and authentication so anything custom I need with authentication which I will need in this project so I can do that with python manage dots Pi start app and I'm going to call it users so here we used Django admin but once we created the project we got this manage.pi so now instead we can run these commands like start project and start app by using this instead it'll be python manage.pi your command and whatever options it has so there we are now we have our users app and then the other thing I'm going to make is my DOT EnV y so I'm going to do a DOT env.local and this is where I'm going to set up my environment variables for my development environment I'm going to close this for now I'm going to come back to this later for now I'm going to go to my settings because this is where I'm going to start configuring some things now in this particular project we're going to end up deploying things to digitalocean so I'm going to do that a little bit later but one thing that I'm going to be using to kind of help out with that whole process is there's this link to deploying a Django app on App platform with digitalocean that a lot of these steps in here are going to be very similar to what we do in this project and I'm also going to have a link to this in the description below so shows you creating your virtual environment and then creating the Django project so we're kind of going through those steps and then later on there's some project setup things that kind of start right here actually so let's say for setting your secret key you can use an environment variable of Django secret key and then you can also use this utility function to generate a random key so we're going to be doing things similar to this so I'm going to show that setup right now so inside of here at the top I'm gonna do from OS I'm going to import get EnV so this is what we're going to use to get our environment variables another thing I'm going to need is to import dot EnV so that was at python.ed package that gives me support for the dot EnV file right here and getting the environment variables from there because by default I can't get those environment variables from this kind of file instead it would have to be environment variables set up on my system itself so this just makes development a little bit easier and then below here another import I'm actually going to need is going to come from OS as well it's called path then what I'm going to do is set dot Envy file this is going to be base directory and then dot ENT dot local so this is going to be this file I made here then I'm going to check if path dot is file dot EnV file so if this is a file then I'm going to do dot EnV dot load dot Envy The Dot EnV file so I'm going to load the environment variables from this if this exists so in our production environment this is not going to exist so we're not going to be doing this loading of the dot EnV file instead we're going to have more like global environment variables on there but in our development environment this just makes things a lot more convenient so I have to go into my terminal and set up global environment variables and it also complicates things from a Windows system and you want to set up these environment variables so this is a much better development experience so I'm going to save that also when I save here I get this little suggestion you have the Auto Pep 8 formatter extension installing would you like to use it as a default formatter yes I would because my default formatter right now is prettier but I'd rather use Auto Pep 8. so then it'll just create this obvious code folder and then in there there's the settings Json where it just sets this up and then I'm going to go back so right here I have this whole secret key set up so I'm just going to copy this and then I'll go paste right over here so right now I don't have to do OS dot to get EnV since I just imported this directly so my secret key that's going to be equal to this and then I need this import as well so that's right here so this will just generate a random secret key and then I can just cut this so this is how I'm going to set the secret key up now and then also I'd rather use single quotes I'll do that and then inside of here I can do Django secret key is equal to this and actually I have an extra quote here so there we go so now we have this environment variable that's going to get loaded up by this and then we'll be using it here then if you don't have this set then you're just going to generate a random one but I'd rather just have one set up in here so that way every time my server kind of reboots I don't want to generate a Brand New Key especially because we're going to be using Json a token authentication and then we're going to have like the cryptography it's going to be using the secret key so that every time it changes then your access tokens aren't going to work so I'd rather just have one that's kind of in place every time my server restarts I hold that value then the next I'm going to do is tackle this setting so here we have debug is equal to this right here so we're going to get an environment variable of debug and by default it's going to be false and then environment variables are always strings so you have to do it like this you can't just grab it and use like a value of true otherwise it's going to be like the string true or the string false so you have to do this kind of comparison and then by default we're going to have this be false equals true which is going to evaluate to a Boolean of false so that way in our production environment we don't have to set this thing it'll just be false and then in our development environment we will have to set it so here I'll do debug is true and again this will be the string true and now if I put quotes around it or if I don't it's the exact same thing so you can use whatever syntax you want inside of here then the next thing I'm going to do is tackle the allowed hosts so that's right here and then I'll paste paste right here so we're going to get environment variable of Django loud hosts which by default is going to be our localhost environment let me do this dot split we're just going to split this into an array and also by the way if you let's say had only one item here and you did a DOT split it would be an array with just one item so that would work you don't need to have the comma there so I saved in that formatted things now I'm going to tackle my installed apps so we have Django rest framework in this project so I have the documentation open here that'll be the first thing I set up so we need to install it which we did you have to put it in your installed apps and also if you want to use the browseable API you can also set up this here but I won't be using the browseable API and set the test out my API I'll be using Postman so let's put this in here so we got rest framework next we got to set up these settings I'm just going to copy this example here and I'll scroll down and I can put that say below the static settings I'll remove these comments and then for my default permission classes instead of having this here I'm gonna have is authenticated so what this is going to do is on all of my views by default we have to be authenticated and then if we're not we're going to get a 401 unauthorized so if we want to overwrite this then we can set a different permission for example we can have permissions of allow any and we have to specifically Define it on The View but I want by default the behavior to be is authenticated so that's going to be for the permission classes we're also going to have authentication classes in particular we're going to be using Json web token Authentication but we can also go inside of Django rest framework inside of Authentication and then here you can see the setting that you need to set for authentication classes so that's this one here and then it has some examples of let's say basic authentication session authentication but ours of course is going to be the JWT Authentication I'm gonna set up that setting here then that's going to be a list and then this is where we're going to set that so right now we have the joser library that we're using and that's also one of the suggested libraries in here so third-party packages joser and then here you can see that it's a library that provides views for handling basic actions like registration login logout password reset account Activation so all of that we get with this and then behind the scenes when we're doing the JWT authentication so I have the documentation open for it it's one of these uh let's see which one this one so here if we also have this JWT endpoints and then these JWT endpoints they're going to be using the simple JWT package so then I also have the simple JWT documentation and then here we can take a look at some of the settings it has you can go to the settings and then you can see the default settings and then there's also how you can set this to be your default authentication class so I think it shows it somewhere out here so default authentication classes you will put this right here and that will use the JWT authentication then so that is what I'm going to paste right here so now I have my authentication classes and my permission classes set up and then also just to show with joser that it's using these simple JWT package behind the scenes you can also go in your virtual environment you can look for joser and then here you have URLs JWT and you can see it's using the simple JWT package and it's just setting up these endpoints and behind the scenes just using the views from there so we have things like the token obtain pair view refresh view verify View and the end points for that so now with that we can go into our urls.pi just gonna remove the documentation comment there I'm gonna have a path which is going to be API slash and there I need to bring in include and then I'm going to include joser.urls so joseph.urls this isn't going to give me the JWT URL so it's only going to give me the other ones if I want the JWT URLs I have to do API slash and then include joser.urls.jwt shows that in the documentation for joser uh this one here and then if we go to settings or not settings that's going to be all of our settings I'm not sure exactly where it is in the documentation like in the getting started but anyway we will need this so here we have Joe sir that we have to put in our installed app so let's just go ahead and do that so back in my settings I'm gonna scroll up I'm going to put Jose right over here and then it shows you how to set up the URLs so you just include joser.urls and then for JWT I'm not sure exactly where it shows that I would expect it to be in the JWT endpoints or maybe somewhere else perhaps sample usage no it's not sample usage but anyway that's how you would set up the JWT endpoints now once we have these simple JWT package set up so these are all the default values so we have let's say the access token lifetime five minutes refresh token lifetime one day then rotate refresh tokens Falls Blacklist after rotation faults and so on so forth and then also one thing that's in here is our signing key so the signing key that's the thing that uses our secret key so this is the reason why I want it to have in the environment variable the secret key because every time it changes the signing key will be different and then your JWT authentication won't work you're going to have to re-sign in and then resigning in when you're using Json web tokens is just creating a new access token and that's because you use your access token for authorization so if you wanted to overwrite any of the settings in here you would just put a simple JWT setting which will be your dictionary you can overwrite any of these settings but I will be sticking to the defaults so I don't need this open anymore I also don't need this open anymore and then one thing I will need is the settings in joser because we're going to be setting these up so going back to the code I'm going to scroll down to the bottom here and then also while I'm at it I might as well set this up I'm gonna have my static root which will be base directory static and then I'm also going to set up media URL and media roots so for the media this is going to be where you have things like photos and videos and whatnot now I'm not going to be using that in this project but it is very common to have it in a project so I'm just going to include it here and then for media Roots it'll be base directory media and then below my rest framework settings this is I'm going to have my joser settings this will be my dictionary and let's see what we need to set up so the first setting we see here is the user ID field so this will be the name of unique field in the user model this is something we can just stick to the default we have the login field so login field this is going to be set to user.username field but this is something that will be overwritten once we create our custom user model so we can just stick to the default on this then we have our password reset confirm URL so this is going to be a setting I'm going to set up so back in here I'm gonna paste this I'm going to set this to password Dash reset and then uid ant token and then we also have username reset confirm URL so this is going to be when you're resetting a username which in our case would be an email now I'm not going to include this one just because we're not going to be doing a username reset which in our case is an email reset now you can include this if you want and it's very similar to how it works with the password reset so once you know how to do this one you'll know how to do this one as well I'll just skip that one and then we have send activation email so this by default is false but I will want this to be true just because when someone creates an account I'm going to want them to get an activation email where then they're gonna have to click a link and activate their account so I'm going to set this to true and then we have send confirmation emails so what's one registers or activates then send the confirmation email so I don't want to send the confirmation email so I'll stick to the default of false and then password change demo confirmation that's when someone changes their password I don't really want to send a confirmation email so I'll leave this app false and then username change demo confirmation we're not going to be doing the username changing so I'll just keep this as false then we got activation URL so I'm going to copy this one so this is going to be the URL for when someone needs to activate their account which will be activation slash the uid Slash the token then we got the user create password retype so this means do we want to have a re-password field when someone hits the create user endpoint so I do want someone to confirm their password so I will set this one to true because by default it's false and then the next one set username retype so this is if you're setting a different username which in our case would be a different email I'm not going to include this we have set password retype now I'm also not going to have setting a password we are going to have resetting a password but setting a password this is in particular if you're logged in and let's say you want to set a different password then this is what you would use and then this pretty much means you have to confirm the password that you're trying to set so that you'd have to include this renew password field I'm just going to set this to false since I'm not going to have that functionality in this app and then I'm going to have password reset confirm retype so this one I will have so this will require the renew password and that's when I'm hitting this endpoint here and that's going to be when I'm resetting a password so I'm resetting a password what we do is we hit an endpoint which is going to send us a reset password link and then we're going to go to that and then we're gonna have to put in our new password and then I don't want to just have one field where I just set the new password I also want to have a user have to confirm that new password this and I'm going to set that to true and then going back we have username reset confirmary type so I don't have username resetting so I'll leave that as false log out on password change that will be false and then password reset show email not found so this is going to be when we're requesting to reset our password we're going to put in our email and then we get the link now this will make it so that if your email it doesn't exist in the database then we're going to get a 400 that request that's if you set this to true but I'm going to leave this as false and in particular it's because of what it explains here so if you set this to true it will expose information of whether an email is registered in the system so I don't really want that so I'm just going to leave it as false so this will always succeed so you're always going to get a 204 no content response even if the email doesn't exist then you don't receive that email and I'm okay with that just so that it doesn't reveal that this email exists in the system then we have username reset show email not found this also false since we don't have username resetting and then we got token model so points to which token model should be used for authentication in case if only stateless tokens like jwts are used in the project this should be none so I'm going to go ahead and do that since we are using jwts the token model that will be none so there we go those are the joser settings the next thing I'm going to do is I'm just going to run this and do python manage.pi run server localhost 8000. and this way I can just see if I made any typos so I didn't make any typos now there's going to be these unapplied migrations I'm not going to make these migrations yet and that's because I want to set up the custom user model first make those migrations and then I will migrate I'm going to stop running this I just wanted to see if any typos are made so far seems like there weren't so the next thing I'm going to do is I'm going to scroll up I'm going to go to my installed apps I'm going to include my users app because I will need this here and then I'm going to start working on that custom user model I'm gonna open this up open up the models and this is where I'm going to work from so to help me out with this process so I have the Django documentation open and I'm going to search for Authentication and then there's this right here which is for customizing authentication in Django then inside of here at the bottom there's a full example of setting up a custom user model so there's a section here it says a full example I'm going to do something very similar to what this shows here so to help me out I'm just going to copy this I'm going to copy everything here I'm just gonna paste it inside of here now there are going to be things I don't need so all of these things I don't need so I'm just going to delete them and then string representation of this model I'll keep it as email and then username field is going to be email I'm going to be using single quotes and then I'm going to have required fields so the username field is what I'm going to be logging in with by default and then required fields or any additional Fields I need to create my account so I'm going to have here first name so when I'm registering I want these to be supplied as well and then this date of birth field I don't want here so I can have this email field I'm just going to get rid of this verbose name unique true all have showing up first I'm just going to reformat this a bit and then because we have first name last name we have to define those so I'm going to first name that'll be models dot Char field I don't have a max length of 255 let's say I'm going to copy down the line and have the last name as well that I'm also going to rename this so I'm going to call this user account then I'm also going to have my objects it's going to be user account manager I'm going to copy this and change the name of this so it's going to be user account manager so this thing is inheriting base user manager and pretty much what this thing is is in Django if let's say we have our user model which is user then we can do things like dot objects dots create user so that is what this objects thing is it gives us access to things like create user and let's say filter and get so all of those things are included inside of this manager now in particular we have this create user which I want to set up inside of here and this is going to overwrite the behavior of creating a user because now I'm going to be using an email and then we have this state of birth field which I don't want here we have the password which by default is none so if this isn't supplied then the creation isn't going to work and then I'm also going to have keyword arguments here so this is going to be a dictionary and then it's going to include things like our first name and last name so that's going to be our extra arguments now you can also let's say do first name and last name here but I like doing it this way more so I'm just gonna keep it like this and then if we don't have an email we're going to raise a value error then here's where we create our user model so what I'm going to do is I'm going to do email is equal to self.normalize email so what normalized email does is if you have something like John Doe at example.com normalizing is going to set this part to be like lowercase so I'll end up with example.com now one thing to note with normalizing an email it only normalizes what's after the ACT doesn't normalize what's to the left of it so if I have John Doe and I put this through the normalized email nothing will change so what I want to do is email is equal to email dot lower and then that way it'll just set everything to lowercase and that way I would end up with something like John Doe at example.com because if someone lets say have their cap locks on or something and did John Doe at example.com the next time I go to sign in if they use lowercase they're not gonna be able to log in so that's where I'm going to have this email dot lower and then here I'm going to have email is equal to email and then I'm gonna have keyword arguments and then after that we're going to do user dot set password of password so this is going to Hash the password then we're going to save the user and we're going to return the user and then joser behind the scenes is going to be using the create user of our custom user model now now I also want the ability to create a super user and then I will want another import ant that one is going to be my permissions mixin and this is something I'm going to have my user account inherit so I'm going to place it in here and that's going to give me some additional Fields like is staff and is super user and whatnot so that will come with the permissions mixing and then instead of using this is admin I'll be using those fields that come with the permissions mixing so right now we have this is active and this thing by default is set to true now this will be flipped to false with joser because of the settings that we have with needing to activate the account so by default even though this right now is true it will be false when we create users now I will keep this default as true here and in particular this is going to be for when we're creating a super user so if I have this default false when I do my like python create or python manage.pi create super user when I go to create that if I have this as false my super user is gonna have is active as false then I won't be able to log in with my super user I'd have to go into the database itself and adjust this to be true just so I can log into my admin panel so because of that I'm going to have this default to be true and then instead of is admin you're gonna have is staff this by default is going to be false then I'm also going to have is super user this will also by default be false so is Staff this lets us log into the Django admin panel and then is Superuser just gives us a super user permission so this right here is what actually gives us the ability to let's say go into the admin panel and edit things so the next I'm going to do is go to this create super user I'm just going to get rid of this doc string and then this has date of birth inside of here I don't want date of birth I want keyword arguments and then this behind the scenes is just going to do self.create user which is literally this function here so we're going to pass the email password and keyword arguments to this thing and it's going to create a user and it's going to return that user so then here the main difference is I'm going to have keyword args so we're gonna get that user which gets returned so the next thing we want to do is we just want to set those properties so this staff we want to set the true and also is super user we want to set to true and then we want to save that and that's pretty much it that is now going to be a super user because they have these two flags at the true so there we go that is our custom user model created so it wasn't too bad but now we have to set this to be used so the way we do that is there's a setting and inside of here if you scroll down you'll see this auth user model you just have to supply the path to it so that's the last thing we have to do and our custom user models in place and we can make our migrations I'm going to go back to my project open up my settings.pi scroll to the bottom and then this will just be equal to users that's the name of our app and then user account all right so now we're in a pretty good spot so the next thing I can do is python manage dot Pi make migrations [Music] there we go and python manage.pi migrates and that will migrate to my sqlite database and now we can just have our server running so I'll do manage.pi run server localhost 8000. and I'm just going to have this running so that if I ever make a typo I can just very quickly catch it so this is something I like to do so I'll close that and then with what we have here we're actually already set to test things out now we didn't set up course headers yet I'm going to do that afterwards it's not really important the course headers are more for the client and that will set up some headers in the responses which then will allow for cross origin requests although if we're using something like Postman we're not in a browser environment so cores doesn't really come into play so cores is more of a browser thing so that's just something to note now we will have to have that set up but to test that what we have right now we don't have to quite do that yet now that is something that we did install but we're gonna get to setting that up after just testing what we have so let's go ahead and see what we got Postman open so you're going to want to do the same if you want to test out the API I'm going to create a new collection and then I'm going to call this full off course I made a typo where's my renaming there it is okay so this is where I'm going to put anything that I want to test out and actually something I have to do before I can even test this out is set up my email settings so that's something I actually didn't do yet so actually so we can't test out quite yet now when it comes to sending emails there's different approaches that you could take and the approach that I'm going to take in this app is by using an AWS service so this service is going to be the AWS SES service and that is a service made for sending emails so that is what I'm going to be using in this project now there are other options you can use things like send to Grid or other options as well but in my case this is the approach I'm going to take just gonna open things up I'm gonna stop running this I'm gonna do a pip install for Django Dash SES so that's going to install that package for me so in the clear I'm going to do a pip freeze requirements txt so anytime I install new dependencies I want to do this just so I can put that inside of the requirements txt clear this up now and I'm gonna rerun my server so let's set this up so we're not going to test quite yet but we're almost there this right here is the documentation for Django SCS so I'm gonna have links to everything I'm using in the description so that we don't have to look at this URL and try to type it yourself it'll all be in there and then to set this up first thing we have to do is install which we did and then you're also going to want to have this in your installed apps but it doesn't seem like they're showing that here there it is so sending oh that's for sending stats so actually we don't want to be sending stats we don't have to include this in our installed app so that's fine what we will need is the other settings so I'm going to scroll up and find this stuff here so first of all we want to set email back end to be this so for my email settings I'm going to find a spot for that maybe below the databases I'll have my email settings so email backend will be this right here and then you're also gonna have to set up your AWS access key ID and secret key now one thing I'm going to be doing in this project is I'm going to be using digital ocean spaces which is very similar to AWS S3 buckets and then that is also going to have an access and secret key so one thing that SCS allows you to do is alternatively set up these settings so AWS SES access key ID and also the secret key and then that way I can have these credentials separated so the one for the digital ocean spaces it's going to be these ones here and the ones for SCS will be these ones here and then behind the scenes they're also using the python Bodo 3 package to do this communication so that's actually something you would see inside of the requirements txt behind the scenes Bodo 3 got installed so what I'm going to do is I'm going to copy this then I'm gonna paste it here I'm also going to grab this paste it here just so that I have these values and then also I'm going to do this use scsv2 so that's if you want to use the SDS version 2 client so I might as well do that so I'll also put that as well I'm going to set that to true so these we're gonna set up in a bit I'm just going to leave them like actually I'll just put empty string for now so it doesn't complain and then we're gonna have AWS SCS region name that's something we're gonna need so I'll put that here and we're also going to need the SCS region endpoint and then for the region endpoint what we're going to do is we're just gonna grab this right here and then paste it here and then this is going to be using the region name so what I can do is inside of here I can just have the region name and I can make this an F string so that way that can get plugged in there so we're gonna have email dot whatever our region is dot Amazon aws.com it's going to set that up and then another thing we're going to need so if we search in here there's AWS SCS from email so this is an optional option so the email address can be used as the from address for the email and that will be the setting here so I'll put that say over here and now I'm going to start making use of the environment variables so I'm going to do get EnV y I'm just going to set this to be this and there is actually one more setting we're going to need and it doesn't show it in that documentation but it's also more particular with joser so if we go into joser and then we take a look at email so let's say if we're sending an activation email behind the scenes this is inheriting base email message and then if we go through this we have context getting set up but we also have the sent now this send it's going to set up the from email and it's going to do it using settings.default from email so it's going to be looking for the setting and that's going to be the from emo when joser is sending emails so we actually have to set this up so I just copied that setting I'm going to go back into here I'm just going to paste that and I'm going to use an environment variable for this and it's going to be the exact same as this AWS SCS from email so we're going to use the exact same value then for the access key I'm gonna have get Envy I'm just going to copy this and paste it here and here as well so for this it's going to be AWS SCS access key ID this empowerment variable is going to be the secret key then I'm going to have region name and there we go these are all the email settings so now I'm going to open up my EnV file I'm just going to start pasting these in there I'm gonna have the access key and I have the secret access key I'm gonna have the region name reach an endpoint we don't need to do and then finally we have this AWS SCS from email which both this setting and this setting will use I'm going to copy that and paste it in here all right so now we have to set this up so right now I have two emails set up so that I can test things out in this project so I have this John Doe 1357933 email address so this is going to be my sender email then I also have a receiver address that's going to be this John Doe one three five seven nine one five gmail.com so this we're going to be using to like register and log in with an account on my application so the next I'm going to do is I'm going to go into AWS dot amazon.com so you will have to create an AWS account if you don't have one then after that you can sign in now in my particular case I set up an IAM user and that's what I'm logging in with so then I can put in the account ID this is my account ID the IAM user I setup and the password now you can also log in with a root account that's also perfectly fine and by default that's going to be your login screen and then once you have your root user you can set up an admin user I'll also show that setup that I have but for now just because I have this IAM user I'm going to log in with it instead of with the root and then if you go into IAM which you can also search for so that's this service so the setup that I have so if you're logging in with a root user the way that you can do this is you just go under this users and then you can just add a user in my case I made a user with the username of admin and then this thing has a policy of administrator access and this thing just gives me administrative access for this particular user now in the case of this particular admin user I attach permissions directly of the administrative access another thing you can do is you can also make user groups so let's say I can have like an admins User Group and then this thing here can have permissions of like administrator access and billing and then you can just have your user be part of the group in this case I just have them as none me just has the permissions of administrative access so that's that part the next thing you have to do is go into SES which is Amazon's simple email service and then also you want to note the region so right now I'm in CA Central one so that's my region so I'm going to do is I'm just going to copy that from the URL just so I don't make a typo then inside of the region name I'm going to paste that in here so CA Central One and then for the from email that's going to be my John Doe 1357933 gmail.com so that's my sender email now we need to set up these two things so inside of here what you need to do is you need to go into verified identities and you need to verify both the sender and the receiver email you can't just tap the sender you need both so I'm just going to go to create identity email address I'm going to put in John Doe one three five seven nine three three at gmail I can create that identity and I'm going to do that one more time so back in here so this right now has verification pending we're going to get to that it's going to create another email address and this is going to be my receiver email so you need to include both or this is not going to work so right now both of these are pending verification so if I go into here so this is my John Doe one three five seven nine one five email so this got an email and that has a link which I can now click and there you go verified and I can do the same thing with my other email address of John Doe one three five seven nine three three gmail.com so here's that link click it to verify and there we go that's all you gotta do to verify so back in my AWS console if I refresh they should now both be verified beautiful so the next thing you have to do is go into my SMTP settings and create SMTP credentials gonna go ahead and do that so we have IAM username we can show more information if we want so this is some stuff it has configured so I can just create this user and this user it's going to have credentials which I'm going to be using and it's going to be responsible for sending these emails so now I can show these credentials now one thing that I found is whenever you create this for some reason the credentials it gives you off the bats don't work and have to recreate them so I'm just going to close and I'm going to go through that process just to make sure that it works so under now IAM users so we are now in iam so right now we have this user created so I'm going to click on this user go to security credentials and I'm just going to remove the credentials it has right now and then you have to deactivate the key before you can delete it so I'll deactivate paste this in and delete and I'm going to create a new access key so it's going to be for local code we have to check this thing and then you can set up tag so I'm not going to do that I'm just going to create the access key and I can grab these values so I can put the access key here go back here copy this and paste in my secret key so I have both of these set up so now I have all of my settings so that emails work and now I'm just going to click on done continue so I already have the secret key copied so if you click continue you won't be able to see this anymore so make sure that you set up those environment variables otherwise we have to recreate these so there we are and then the next thing I'm gonna have to do as well is going to permissions so right now we have this permission of Amazon SCS sending access which just gives you an allow action of SCS send Rock email but I will need another permission to have sending emails work so I'm just going to do that now I'm gonna go add permissions and then I'm going to use attach policies directly I'm just going to search for SES now I don't need SCS full access what I do need is I think it's yeah read only access because I do need this get access and that I get with this policy so I'm just going to attach that one so click next add permissions and now we have this as well so with that we are now all set up with SCS so now we can test out our backend API so I'm going to now open up Postman once again and let's test these endpoints out so the first thing I would want to do is create a user so let's actually also make sure that our server is running so it is and actually I'm going to restart the server just because I added these environment variables so I want to make sure it picks that up so I'm going to rerun and then I can also just close this stuff up and now let's take a look at the endpoints that we have so back inside of my jokester settings or I guess inside of the documentation you can go to base endpoints and here is our user create endpoint so we're going to be hitting this endpoint here in particular when we set up our URLs we prefix this with API slash so our endpoint we're going to be hitting is low cost 8000 slash API users and then slash so make sure to have that trailing slash there that is important then these are the things we have to put in here the username field required Fields so we Define those in our custom user model so we have username field that's email required Fields first name last name and then if we get 8201 created this worked for 100 bad request means this didn't work so let's try this out it's a local host 8 000 slash API slash users slash so again make sure to have that tree link slash there we're gonna have content type of application slash Json and then I'm gonna send some raw data it's gonna first name which will be John last name if we go email this will be my John Doe one three five seven nine one five emails this is my receiver email I'm gonna have password and I'll do my secure password and then I also need the re password so let's test out what happens if these don't match real quick password field didn't match so that means we set things up correctly to have these two get compared I'm gonna get rid of that I'm gonna click on send and there we go we got a 201 created and we get back our data so first name last name email and the ID of the user so perfect I'm Gonna Save this now this will be my create user and I'm going to save that in full auth or so now the next I'm going to do is test out logging in which should fail right now because our account isn't activated so I want to test that behavior so that endpoint is going to be localhost 8000 slash Epi slash JWT slash create slash now you can also go into the JWT endpoints and you will see these endpoints here so we need to pass the username field which is our email and the password in a 200 okay with an access refresh token means things worked a 401 unauthorized means things did not work and then we're also going to be testing out this refresh endpoint and the sparify endpoint as well so let's go ahead and put in our content type of application Json and my body which will have the email password which is my secure password so let's send this so no active account found with the given credentials so that's what I expected so now we have to go to the activation process so back in here we received that email successfully so that's really good now another thing that we're going to notice is here we have the localhost 8000 team and we also have this domain being used here now these are things we're going to want to customize so in particular here I want to have something like the my full auth team or something like that and then here I'm going to want localhost 3000 instead of 8 000 because my front end application is going to end up running on localhost 3000 and also when we're in production we're gonna have our API on a subdomain of API Dot thedomain.com and then the front end next.js project is going to just be on the domain.com so when I get this link in production I also don't want it to be like api.mydomain.com this activation link so that's something we're going to edit but before we do that I'm just gonna copy this actually I'm gonna copy this part here because we have the uid and the token I'm going to want those values in order to activate the account so back inside here we're going to do localhost 8000 slash API slash it's also gonna be a poster Quest and let's take a look at the endpoint we have to hit so back in the joser settings I'm going to go to base endpoints and here we have user activate so this will be users slash activation slash with the trailing slash and we're going to put in the uid and the token in a post request so 204 no content means this worked anything else means it failed so user slash activation slash content type in the body I'm gonna have the uid I'm just going to paste this whole thing and the token so the token is this part after the slash so I'm going to cut this I'm going to delete that slash put in the token and this should be good so now what I'm going to do is I'm just going to add an extra character just to test out that this works so there we go we got the 400 battery Quest because the token was incorrect so now if I get rid of that additional character this should not work I'm gonna send this there we go 204 no content so the activation succeeded so I'm going to save this this will be user activation and now this should work so I'm gonna try the JWT create once again and now we get the access and the refresh token in the response body it's perfect so we tested out those endpoints now let's test out the other jwtn points I'm going to copy this paste so we're going to have our refresh endpoint that would be a post request if we go into our JWT endpoints the refresh we'll just expect in the request the refresh token and the response will be at 200 okay with the access token so let's put in the content content type a pass raw data with refresh and that would be the refresh token so here in the response we got that refresh token that go back here I'm going to paste it I'm going to add an extra character just to test the non-working Behavior so there we go token is invalid or expired now if I get rid of that it should now work there we go 200 okay with the access token I'm Gonna Save this there we are and the last JWT endpoint I will test is the verify endpoint this will be the poster quest to API JWT verify and here I'm gonna have content type location Json then as for the data what we have to pass is token and this token will be the access token if everything works 200 okay otherwise 401 unauthorized so let's try this out open so this will be the access token I'm going to copy my access token go back here and paste it I'm going to put an extra character just to test out the non-functioning behavior there we go token invalid or expired if I get rid of the extra character send there we go now if it's been over five minutes then yours might have just gotten as invalid so if that's the case just hit this endpoint one more time grab a new access token and then you can test out the verify endpoint because remember by default access tokens expire after five minutes Gonna Save that JWT user verify so I'm going to close these up so now going back the other base endpoints we want to test so we did the user activate now we also have retrieving a user so it's going to be users slash me slash so localhost 8000 slash API slash user slash me slash this will get the current user and this is an authorized route so if I were to send this as is it's not going to work I need the authorization header that's by default how this works you can have authorization then you're gonna have bear so that's the auth header type and then the access token so I can copy the access token and I can paste it after bear so bear space access token send this you should now get back the user with the 200 ok now this Behavior with passing the authorization header this is something I'm going to overwrite for now just testing out the default Behavior but we will come back to this that we're not going to need an authorization header instead we're going to have HTTP only cookies which are going to have our access and refresh tokens so we'll get to that a little bit later I'm going to save this as retrieve user and then next we've got to user delete I'm not going to test that one you have set username set reset username so all these I mean I skip same with set password so I want to test out reset password so this one's going to be this endpoint it's going to be a poster Quest where we pass in the email field so post request localhost 8000 slash API slash users slash reset underscore password slash I'm gonna have content type location Json then in the body just gonna have email and I'm gonna have John Doe one two five seven nine one five gmail.com and actually before I do this what I'm gonna do is I'm going to edit the template settings just because I was the one thing I was mentioning before so I'm gonna have to go back to my code and then in particular if let's say we go into joser so previously we were looking at this email and we had things like activation email then we also have other things like password reset email and these things use these templates so these templates we can find here we have templates email and all of these I open up let's say the activation one what we're going to notice is in the context we have things like site name we have things like domain so somewhere this context is getting passed so here we'd have the protocol like let's say HTTP localhost 8000 and whatever and same thing here so HTTP the domain which might be low cost 8 000 and then slash whatever you have here so that would be your href and then also you'd have what you display and then also site names so let's say the full auth team so how can we edit these well let's take a look right here what we have is this get context data and this get context data is calling get context data from the parent class so that is this right here what we're inheriting so if I visit this we have get context data and then if we take a look we can see some things getting set up here so in particular we have this domain it's equal to context.get domain or you get this domain from your settings and then protocol yeah I'm doing it like so and then we have site name grabbing it from the settings site name and then we have users equal to context.getuser and then finally we have context update we're then we update domain and site name protocol user to what we have here so then in the context itself this domain that we get from the settings and the site name that we can get from the settings will be inside of the context and they'll be plugged into this template and same thing for the other templates as well so knowing that what we can do so I'm just going to close up all this now so we can now go into our settings and we can set these settings up so I'm going to set those up right below here so I'm gonna have my domain and this I'm just going to get from an environment variable called domain and then I'm also going to have site name and this I'm just going to set to like full auth because this will be the same in both development and production I'll just have this this will be whatever your site name is and the next thing I will do is go into my EnV local and then set up the domain and then the domain in this case it's just going to be localhost 3000 because later on that's where our next GS application is going to be running so now that we have that I'm going to restart the server clear and do pythonmanage.pi run server with low host 8000. and then back here now I can send this request off so 204 no content let's see if it worked there we go we got the email and now what we're going to notice is here instead of localhost 8000 we have low cost 3000 and then further once we're in our production environment we can also set up this domain environment variable and set this up to our domain so that way this will work in production too and then we just have the URL and then here we have the full auth team so it looks a lot better so now we're going to do is I'm going to copy this part that's our uid and our token and then also this right here by the way it's following what we set up in our settings so that was for the joser settings so right over here we have password Dash reset slash uid slash token so it's following that scheme for the password reset confirm URL now you can also set this to whatever but this is what I have in my case you can even have it as like let's say reset uid token but you do need the uid and the token in here so going back now into Postman we can send off a new request and let's see what the end point here will be back inside of Joe sir this was reset password Here we have reset password confirmation so this is going to be slash user slash reset password confirm slash you have to pass qid token new password and renew password if it works to a for no content otherwise 400 bad request so let's test that out so slash users slash reset underscore password underscore confirm slash double check that reset password confirm slash good and then we're gonna have our headers content type location Json passing raw data now pyd I'm just going to paste in that which I copied so that was just inside of that email this part right here pyd I'm going to have token and then token it's gonna once again like in the activation email be this part after the slash I'm going to cut that I'm going to delete the slash I'm gonna paste this in the token part then I'm gonna have new underscore password map my secure password one and then I'm gonna have re new password which will be my secure password to so I'm going to test when they don't match and see what happens two password Fields didn't match perfect so that is because of this setting right here password reset confirm retype so that means that we have to have that confirmed field which is this field right here and they both have to match I'm going to set this to net match I'm gonna click Send and we get a tool for no content which means that this worked so I'm gonna do password reset confirm save that I'm also going to save this one as request password reset and there we are so we have all of these and now if I try to log into this right here using my secure password now I get a 401 unauthorized because we successfully reset the password to now be my secure password one so there we go now I get the axis and the refresh token so now we tested out all of these endpoints now the next step I'm going to do is I'm just going to quickly set up these course headers it's not going to change anything for us but it is something we're going to have to set up and then inside of Django course headers so there it is these are the things you have to set up so in our installed apps I want to have course headers it's going to go to my installed apps and I'll put course headers here you also have to set up middleware for this I'm going to copy this I'm going to place this middleware above the common middleware and then all that this is going to do is it's going to set up some headers that I need to set up when I send responses from my server and then that way on the browser I can have these cross origin requests not get blocked by the browser and then I also have to set up which Origins are allowed so you can do that with cores allowed Origins so I'm going to copy this I'm going to go back here and I'll scroll down and put that somewhere at the bottom maybe below my juicer settings and then I'm going to have get EnV Y and it's going to be the same as this here and then that way in production I'm going to set up whatever my course allowed Origins are that'll be my production URL and I'm also going to have a default which is just going to be http localhost 3000 and also http localhost or sorry not localhost but one two seven zero zero one colon 3000. and then I can do a DOT split on the comma so that way when I'm running my next JS front end I can allow cross origin requests to this right here which is where nextgs is running and I'm also going to format this a bit so it looks better and then the next thing I'm going to do is I'm also going to have a course allow credentials which is going to be true so this right here in my responses is going to set up a cross origin allow credentials heading and then what this is going to do is it's going to allow cookies to be getting sent cross domain so we're going to need that because when we have different ports that counts as cross domains in our development environment we have glucose 3000 and 8 000 for the next JS front end and for the Django back-end API in production we're also going to have different domains or cross Origins because we're going to have let's say our domain.com for our next JS front end and we're gonna have api.mydomain.com for the back end so this is something we have to include and then from the front end when we make Ajax requests we're going to include an option called credentials include and that's going to allow the cookies to get included in the request and we're going to need this so that the browser doesn't block the cookies when they're coming back and so those are things that we have to do in order to manage the cookies now we're also gonna have to adjust some other things because there are settings in a cookie that will prevent it from being cross-domain even when we have these things so we're going to get into that but this is what we need for now with our chorus setup so I'm going to save that so the next thing I'm going to do is I'm going to start to override the behavior of Jose and simple JWT so that way I can get the behavior I want instead of having to put that authorization header inside of my requests whenever I want to make an authorized requests I just want this to be managed by HTTP only cookies so that pretty much just means cookies that have the HTTP only flag set to True which just prevents JavaScript on the front end from reading the values of our access and refresh tokens when they're stored in the cookies so it's just a very secure way to store these cookies but we also need a way to have our authorization process actually read these values so to do that what I'm going to do is I'm going to create a new file inside of my users app I'm going to call it authentication.pi and then right now in my settings my default authentication classes is this right here so right now it's going to be a little bit different so I'm going to copy this I'm just going to paste it here because what we're going to want to do is from rest framework simple JWT authentication I'm going to want to import JWT Authentication and I'm going to want to override this so I'm going to do it's going to make a class called custom oops custom JWT authentication and that's going to inherit JWT Authentication and we're going to override its authenticate method so we got some Auto filling here so if I click into this and look at authentication this right now is how it works it gets the header if the header is none we return none so this in particular something we're going to want to override because we're not going to have a header but we're still going to want this to work because we're going to want to get the values from the cookies instead and then we get the raw token so because inside of the headers they have things like bear token so this will just get the raw token it'll make sure it's there it's going to validate it and it's gonna return so I'm just going to copy what's in here go back into my authenticates and I'm just going to paste in here so we're gonna have self and request and then I'm just going to wrap all of this in a try except just to make sure things work and if they don't I'm gonna return none so first I'm going to do is I'm going to try to get the header now if the header is none instead of returning none I'm just going to get the raw token from the cookies so the way I could do that is raw token is request.cookies dot get and I'm going to get an access cookie I'm going to expect there to be a cookie called access I'm going to retreat it another thing I'm going to do is I'm going to go into my settings and maybe right over here I'm going to set up a setting which will be auth cookie I'm going to set that to be access and then what I can do is from django.com import settings and then instead of doing access hard-coded like this I can do settings dot auth cookie those are some nicer way to do this part and then I'm going to have an else so if header is none we're going to get the raw token from the cookies otherwise we're going to do it like it was doing before using the header and paste this in the else block so there we go pretty easy to override this and then we're going to see is raw token none if it is returned none I'm going to validate it just like before and we're going to return now the only other thing we have to do is go back to our settings and then go to our authentication classes we're no longer using this we're going to be using our custom one so custom JWT authentication which is going to come from our users app dot authentication dot custom JWT Authentication so now anytime you make an authorized request we're going to use the cookies right now we're authorized requests they are going to work because in our authentication file we are expecting to grab from the cookies the access token cooking however we still will have to override some things for the views in order to have these cookies get set and have them set with the appropriate options and then that way this whole thing is going to work so let's go ahead and get started on that so inside of my users app in the views.pi this is where I'm going to get started with overriding some of these views in particular the views that I need to override are going to be the ones related to JWT authentication so the create view refresh View and verify View so one thing I'm going to do is I'm going to import my settings from django.com import settings and then in my settings I'm going to Define more settings than just this auth cookie and then I'm going to be using those for some settings related to these cookies so I'm just going to grab them from here to have them in one place and have these settings just be correct so that way I'm not like hard coding things across my different views so it's just a nice way to kind of organize things so while I'm here I'm just going to set these up so I have my off cookie already I'm gonna have auth cookie access max age and then this I'm going to set to 60 times five so that's going to be 60 seconds times 5 which is five minutes so by default my Json left tokens or the access token they expire after five minutes so I'm just gonna have this match that so the cookie is going to expire after five minutes as well as the access token it's gonna have the synchronization be proper and then I'm also gonna have a max age for my refresh token now this one's gonna be longer this one's gonna be 24 Hours by default so I'm just going to match that by doing 60 times 60 which gives me an hour times 24 gives me a day and then I'm gonna have auth cookie secure so this is going to set whether we need an SSL certificate or I guess an https Connection in order for these cookies to get sent in the requests and their responses so in my development environment I'm going to want these to be false but in production I'm going to want it to be true that we do need to have a secure Connection in order to have these cookies get sent in the requests and the responses I'm gonna do is I'm gonna put in get enp and I'm gonna get an off cookie secure environment variable which we're gonna set up by default I'm gonna have this be true and then equals true so that way in the production environment we don't have to set this thing up it's just going to be true by default entry equals true is just going to give us the Boolean of true but in my development environment I'm going to want to have this thing set up so I'm just going to put it here and it's going to be false now another thing we're gonna need after this is off cookie HTTP only so this is going to set the HTTP only flag on that cookie so that way JavaScript can't access the values in the browser I'm gonna have the auth cookie path which is just going to be slash in our case and then I'm also gonna have auth cookie same site which I'm going to set to none so for same site you can either have strict you can have Lacks or you can have none so strict means that in order for these cookies to get sent the domains they have to match so this will restrict where you can't have these cookies get sent across origin that's what we have strict which means that my front end would have to be on let's see my domain.com and my backend would also have to be on mydomain.com they'd have to be on the exact same domain the exact same ports so that's if you have strict now in our case we're going to have these be cross origin and I'm going to want these cookies to get sent across origin in order for that to happen I can't have the same site property as strict now I can have lacks but what lacks would do is it's going to allow these cookies to get sent cross origin but only on safe methods so safe methods are things like your get method your options method your head method so these are your safe methods but if we have things like posts and puts and patch and delete and so forth these cookies won't get sent with Lacks so in order for that to happen to have cross origin cookies getting sent I need to have none here so that it also works with those other methods because in particular I will need that to work because even for these views I'm about to override like my create view the refresh view verify view these views are all post requests and I'm going to want these cookies to get sent with those poster quests so I need same site to be set to none so that's going to be all the settings I need hopefully all of these make sense and then there's also going to be a domain setting that gets set by default and that's going to be the current domain in our development environment it's going to be localhost and our production environment is going to be api.thedomain.com so that domain property it's going to make these cookies only valid when they're getting read from here and here being our API server so now let's go ahead and go back here and what I'm going to do next is I'm going to import those views we need to override so those are coming from rest framework simple JWT dot views and then we have our token obtain pair view this is for the create you have the token refresh View this is for the refresh endpoint and then we have token verify View verify view I don't think I explained it but the verify view just verifies whether our access token is still valid so the next I'm going to do is I'm going to set up a class which is going to be my custom token obtained pair View and this thing is going to inherit token obtain pair View then we're going to want to override its post method so by default the way that this is going to work is it's going to generate the access and refresh token and it's just going to send them in the body of the response but I don't want to just do that I also want to set the access and refresh token in the cookies so I'm going to put in self requests args and keyword arguments here and then the way that I can do this is I can just call the super method post passing in requests args and keyword arcs so this super class is just a token obtained parody just like before I'm going to capture that response and then I'm going to check was this successful I can do that with response dot status code equals 200 because 200 means this was successful if that was then I'm going to get the access and refresh tokens I'm going to set the cookies and then after that I'm just going to return that response so before I return the response I want to set those cookies because by default this token obtained pair view will not do that so I can get the access token response data gets access is where I get that from and then we have refresh token which is response data get refresh now the next step is just to set these cookies so I can easily do that with just response dot set cookie then in here I'm going to have access that's going to be the name of my cookie and then I'm going to have the value this is going to be access token so that's the access token I got from the response of this token obtained pair View then I'm gonna have a couple of those settings so I'm going to have max age which will be settings dot auth cookie access Max age then after max age and which will be settings Dot auth cookie path so this is that slash path it's gonna have secure it'll be settings dot auth cookie secure have the HTTP only flag which will be settings dot auth cookie HTTP only I think I named it like that yep HTTP only and then finally I have the same site which is going to be settings dot auth cookie same site so these are all the settings I need in order for this cross origin sending of these cookies to work with the access token and then I'm also going to have response dot set cookie for my refresh which will be my refresh token and then the settings will all be very similar so I'm just going to copy this and paste it the only setting that's different is the max age so that one is going to be auth cookie refresh max age so that's going to be that 24 hours instead of the five minutes for the access with that we overwrote this one so now we just have to do the rest for the refresh and the token verify so let's go ahead and do that I'm going to copy this I'm going to scroll down I'm going to create another class which will be my custom refresh view or I guess token refresh view I'm just going to override the token refresh review so we're just going to inherit that and then we're going to override the post and then for the refresh View so remember inside of Postman for our refresh so we received the refresh in the body and then it's going to send us back in the response and access token and it's going to be inside of like Json data in their spots but instead I want to have that access token get set inside of the cookies so going back to the code what I can do is I can grab the refresh token from the request this case we're going to have this refresh token be present in our cookies so what I can do instead of grabbing it from like the body data I can grab it from cookies I can do cookies dot gets refresh and then if we have a refresh token then we're going to set request dot data refresh to be the refresh token and then we're going to call the token refresh views post request and then we're going to have this inside of the data so we're going to grab it from our cookies put it in the data and then send the request off so response will be the Super class post request args and keyword args then once we have that we're going to check is the response status code 200 that means it was successful and eventually we're going to return the response but before we do we want to set our access token so we're going to get the access token value so the new value after hitting this and that's going to come from response data get access and then from there we can just do our response set cookie and that'll look pretty much the exact same as this right here I'm just going to copy this and paste it here and there we go now we don't have to do anything with the refresh token now there are settings you can set in simple jwts so when you hit your refresh endpoint you get back a new access token and a refresh token so this in particular has to do with rotating tokens so that's one of those settings there and then if you do that then you could also get back your new refresh token and set a new refresh token but I didn't set that setting so this is the way I'm handling it and then the last thing I have to do is the verify View so we're going to grab this verify View I'm going to have a class for custom verify view or token verify view it's going to inherit the token verify view it's going to be a poster Quest let's self request args and keyword args and then this right here we are going to send this request to the Token verify view with that token piece of data in the request and then we're going to get the response which is just going to be like a 204 no content if it was successful so that's going to be what checks whether the access token is verified or not which means that we are still logged in that's what I can do is I can grab access token for my request cookies access then if I have an access token then inside of the request data token I'm going to place that access token and then all we have to do is return calling the super classes post passing in request args and keyword arcs so if we have this we're going to put the access token inside of token just like we did when we were testing this out in the body we had this token so now we're just grabbing the value from the cookies placing it in the request body and we're just sending the request off to the Token verified View and that's how we deal with having these cookies so now we have these we're also going to set up URLs and instead of using the Joker URLs JWT we're going to use our custom ones but there is one more thing we have to do and that is create a logout View so when you deal with Json web token authentication the notion of logging out is more just like you get rid of your access token your access token is what you use to make authorized requests and then if you store it somewhere and you just delete it now you no longer have that token so you can't let's say make authorized requests they're not logged in so that's kind of the way that this works now right now we're dealing with cookies so one good way that we can deal with logging out is that our storage mechanism is that we have an access refresh token in our cookies and we just have to delete these cookies that's what I'm going to do to do that is I'm going to create a log out view this is going to inherit API view which I need to import so I'll do that so here so from rest framework dot views I'm going to import the API View I'm also going to need a couple other Imports so from rest framework doctor response I'm going to need response and also from rest framework I'm going to need status it's going to be for setting status codes in the response so I'm going to scroll down and then this is going to be a post request we're gonna have to be authorized in order to hit this route and it's just going to delete our access and refresh token I'm going to pass in self request args and keyword arcs and then response it's just going to be response we're gonna have a status of status dot HTTP 204 note content then we're just gonna do response dot delete cookie I'm gonna delete access we're also going to delete the refresh cooking so this is how we do this in Python with Django and then we're just going to return that response with our cookies being deleted and there we go so now the next step is going to be inside of users to create our urls.pi file and create URLs for these custom views we created I'm just going to close up some of these other files I'm not using right now so first I'm going to do is from My Views I'm going to import these views I made so my custom token of Team pair View custom token refresh View custom token verified View and my logout View my URL patterns is going to be my list then here I'm gonna have my different paths so in the root I'm going to have API slash and then I'm going to have here JWT slash create slash so it's going to be the exact same endpoints only differences we're going to use our custom views and then another thing I have to do is import path so from Django URLs that's where I'm going to import that and then I can grab this view paste it and do dot as view because this is a class based view so I have to chain on dot as View I'm just going to copy down a couple times because I'm also gonna have a JWT refresh just going to use the custom refresh View and I'm also going to verify that's going to use the token verified View and then this has to have it or where's this bear if I there we go make sure that's spelled right the last thing I'm going to need is my logout so I'm just going to do logout slash it's going to be with the trailing slash and this should be logout View and then log out view dot as View so there we are we have our URLs the only thing we have to do now is go into our project urls and instead of using joser URLs JWT now for rjwt endpoints we're instead going to use our users urls so this is our users app the URLs we just defined and there we go it's the last thing to do now is test out that this works so just to be sure since I added some settings I'm just going to rerun my backend server then I'm gonna go to postman and I'm going to test this out so first of all I'm going to hit this create So currently we don't have any cookies now if I send this off we should have two cookies so in our response we got the two cookies and then we have all the settings that we set we have the domain default to localhost so that's good and then in here we also now have an access and a refresh token so now with the retrieve user view previously we're using the authorization header and we can still use the authorization header although I can also not have it send this request and there we go we get back our users so this still works even without the authorization header now and this is going to make things much easier for us because now we can have these credentials be secured in an HTTP only cookie where the front end it cannot read the values of those values with JavaScript but we're also going to have these automatically beginning sent in our requests from the front end and we're going to be able to use them to authorize any endpoint that requires authorization so now in particular the way this is going to change some things it's here we're still going to get back this data now we can override this to not do that but might as well also have the default Behavior working as well so you can use things just like you used before with simple GWT but you also have this added functionality of the HTTP only cookies storing the credentials then in refresh how this is going to change some things previously we needed to do this we needed to have content type application Json with the refresh but now we no longer need this I can just delete this and I can delete the content type application Json save that and I can send this and it'll still work I'll have the access token then in my cookies I'm going to get the brand new access token I'm just going to get set here same with verify previously I needed this in the body and I needed the content type application Json I no longer need that I can just send this off and there we go 200 okay this was verified so our endpoints work then the other thing we can now test out is also our logout we have a post request localhost 8000 slash API slash logout slash it's gonna have the trailing slash this will be my logouts or maybe user logout and I can send this off so I get a 204 note content and my cookies are now gone which means that if I go to retrieve my user I'm now unauthorized and then of course we can go create our user again there we go access refresh token are here again and now retrieving the user will work so there we are we've now successfully overwritten the behavior so that we can have these credentials stored in HTTP only cookies now just one final thing to do for this back end and we're going to be all wrapped up well actually not just one thing because one thing we will have to do is set up the oauth with Google and Facebook but we're also gonna have to go back and set up our static settings to use digital ocean spaces and we're gonna have to deploy this back and so a couple more things but we're almost there okay so let's get started with setting up oauth in this project so first thing I have to do is go into my settings and then inside of my installed apps there is something else I will need which is going to be social Django I'm going to save that now when I put this here there are going to be additional migrations I'll have to make and I guess in particular I'm gonna have to migrate I'm going to stop running this I'm gonna do a python manage.pi migrate and that will migrate to things from social Django to my sqlite database and after that I can rerun and then after that we're gonna have some settings we're gonna have to set I'm going to scroll down and say right above rest framework I'll put Authentication backends which will be a list and this is where I'm going to set up the back ends now we're gonna have one in here which is going to be Django con trib auth back ends model back end so this one here is going to make sure that our default Behavior we have right now works that's going to be one of our backends but we're going to have additional ones as well for the oauth so the oauth ones are going to go above here I'm going to have social core dot back ends dot Google dot Google oauth 2. and then we're also going to have social core back ends Facebook and then Facebook go off too so that's going to set up these two as well and then those you can even find inside of your virtual environment because we have social core in here and then we have back ends and then we have things like Google which is right here and Facebook which is right here so the base Google oauth 2 which is this one here that's the one that we set up is one of our Authentication backends and then Facebook oauth 2 was the other one so that's where these are coming from just so that you understand how these paths work and then the other thing we have to set up is with joser so if I go back to the documentation for joser just right here we have social endpoints and then to set these up you're going to go into your url patterns and then you're going to include joser's social urls but the thing is with these social URLs it's kind of similar to what we had with the JWT where when we get a response we're going to get back the access and refresh tokens except those are going to be in the response data I also want these to be stored in the cookies so I actually will have to override the view that handles the social authentication and then part of my user's URLs I'm going to have an endpoint which is going to do this like o slash provider stuff and then if we look here we're going to have two different kinds of requests that we make to have the social authentication working we're gonna have a get request which is going to give us a redirect URI which we can visit and then once we visit it we're going to do things like log into our Google account or log into our Facebook account and then we're gonna get redirected somewhere and then for where we get redirected we're going to set that up that's going to be one of our joser settings we set up we're going to get a code and a state and then we're going to pass those in a post request and that is what's going to actually do our user creation and get us our access and refresh tokens and then these also aren't going to be application Json right here it actually specifies we're going to have application and then this x www form URL encoded format so they're going to be inside of the URL itself so we're going to get to that but before that I'm going to go to my settings and then here we have the auth token strategy so that is right here by default it's using this right here which is the JWT token strategy so that's actually what I want so I'm not going to touch that setting I'm just going to use the default the other thing we need is social auth allowed redirect Uris so by default it's empty this is where we set where we're allowed to redirect to which is going to be our front end app so in development it's going to be localhost 3000 slash some endpoint that we're going to expect to hit which is going to make that poster Quest and then in production it's going to be our domain.com whatever that endpoint is so I'm going to go back to my joser settings I'm going to add this setting in here and then this setting the way I'm going to handle it is I'm going to get an environment variable called redirects urls and then I'm just going to do a split with comma similar strategy to what we were doing before because the setting will be an array and this will just be a comma separated list and then also just so that in my development environment I don't have to set this up actually maybe I will just have this in my development environment yeah that's how I'm going to do it I'm going to redirect URLs that's going to be my environment variable then inside of here it's going to be my comma separated list I'm going to have http localhost colon 3000 because that's where next GS will be running and I'm gonna have slash auth slash Google and then comma I'm just going to copy this and paste it here and have Facebook so then we're gonna grab these values we're going to split them into an array that's going to be our redirect URLs that we're allowed to redirect to so I'm going to expect next JS to have this route and this route and then this route it's going to handle the poster quest for Google oauth and this one's going to handle the post request for Facebook oauth and also here I noticed I put an extra o let's try not to do that so Facebook there we go so this is all set up now and then because I set up some environment variables I'm just going to rerun also seems that we have an error on split in particular that's because we got a nun type that we're trying to split on so that's not going to work so once I we run we're actually going to have a string value and we're gonna be able to do that split so that's all going to work now close that up and then after this we're gonna have some other settings we're gonna have to set so I'm going to set those maybe right here so what we're going to have is Social auth Google oauth 2 key we're going to get this from an environments variable which is just going to be say Google oauth 2 key or I'll call it Google auth key that I'm going to have social off Google oh off two secrets this will be Google auth secret key and then social auth Google oauth to scope I'm going to set this is going to be a list where I'm going to have https www dot Google apis.com slash user info dot email I'm going to copy this down a line because I'm also going to have profile and then I'm also going to have open ID so these additional Scopes are just going to let me get some additional values that I wouldn't get by default so getting the email first name last name things like that I need to set up these scopes for and then I'm gonna have social off Google oh off two extra Theta which is going to be my first name and my last name and then after that I'm gonna have to set up the Facebook settings so I'm gonna have social auth Facebook key that's going to be an environment variable Facebook auth key social off Facebook secrets so that's going to be Facebook auth secret key and then social auth Facebook scope or I'm gonna have email and then social auth Facebook profile extra params it's going to be a dictionary with fields which are going to be comma separated which will be email first name and last name so there we are and then that way I can also retrieve the email first name last name when I log in with Facebook oauth 2. so these are going to be all the settings we need the next thing is going to be to actually get these keys so that I can actually do the oauth so that's going to be our final step and then we can test this out so to do this I won't need the Joker documentation anymore I believe or maybe I'll leave it open just so that I can go back here and show this and then what you're going to want to do is you're going to go to console.cloud.google.com we're going to log in with your Google account and then you're going to create a project so you can do that by just clicking here clicking new project I'm going to call this full off and create you don't need an organization you can do no organization I just have this here and that's going to go create the project so we're going to wait for that to finish there we are so after that you can navigate into the project so once we see full auth here we know we're in the project and then we're going to go to apis and services and credentials and this is where you set up your oauth login credentials so that's going to be right over here now before we do that I'm going to do this consent screen since I'm getting this popping up so configure consent screen and here for user type it's going to be external so I want users outside of my app to log into my app using their Google account so that's going to be this full off off now my support email and then these settings you don't have to set up you can have authorized domains which we can get back to later and then developer contact email I'm going to save and continue after that I'm going to add some Scopes so that's going to be these three Scopes here and I'm going to update so that they're present and then save and continue and then you can add test users if you want so I'm going to add a test user in my case I'm going to have John Doe one three five seven nine one five gmail.com be my test user I'm going to add that so there we go and then save and continue and here's my summary I can just go back to the dashboard now and then when you're ready to deploy you would just go publish the app so I'm going to go back to the credentials now I'm going to create credentials and I want oauth client ID the application type will just be a web application called full auth and this is where I have authorized JavaScript Origins so in joser when we're doing this get request we're passing in a redirect Tri now this redirect URI someone can go make a request a slash o slash your provider pass in some redirect URI that goes maybe their website but the thing is this authorized Origins and authorized redirect Uris will prevent this process from working if someone tries to redirect somewhere outside of what you specify here so this is a security related thing around oauth so here I'm going to put in my authorized JavaScript Origins so here I'm going to have HTTP colon slash slash localhost 3000. because it's going to be our next GS app that we're redirecting to and then for authorized redirect to your eyes and I have http localhost 3000 slash auth slash Google and then later we're going to come back here once we have our domain we're also going to add that in as one of the Uris and also have the redirect URI for the domain I'm going to create that and just click on actually I need to copy these so I'm going to copy the client ID and then inside of my EnV local actually first I'm just going to copy these into that EnV so I'll do that above the redirect copy the secrets then I'm going to copy the Facebook auth key and on the Facebook auth secrets so now I just have to fill in all of these so back here I'm going to recopy that client ID I'm going to paste it in the Google off key I'm going to copy the client secrets and I'm going to paste that here and Save I'm just going to rerun my server just to make sure that we have those because now we're ready to test our Google oauth so I'm going to click OK that's going to close that up and now let's test this out it's going to open up Postman then I'm going to close up some of these other things so first of all we're gonna have our get request this will be localhost 8000 slash API slash o slash the provider which in our case will be Google Dash oauth 2. and then I believe there's a trailing slash let's just double check yep there will be a trailing slash so I'm gonna send that off and of course we did not yet set up the URLs so let's go ahead and set up the URL so that this actually works and before we set up the URLs we do have to go into our views and override the default view that's used for this oauth so the view that's used for this we can actually take a look we can go inside of joser and then social and then views and we have this provider auth view this is going to be the thing that we override now the only thing that we see in here is a get but this also does handle a post through the create API view which is one of the generic views and then we are going to want a URL for this now we can either set up like we saw in the settings where we use the joser social URLs to set up those URLs but we're going to want our own custom one because we're going to override this in particular we're going to be overriding the post so we're going to send the post request to the parent class which is just this provider auth view I'm going to get the access refresh token then we're going to set those in our cookies and send back the response that's how this is going to work just gonna close this up and then back in our views I'm going to import from joser.social.views we're going to import that provider auth View and we're going to create a custom provider auth View which is going to inherit this one we're going to define a post let's solve for quests args and our keyword args and then we're just gonna get a response by calling super dot post so this is just going to do whatever the provider auth view did we're going to get that response and then we're going to check if the response.status code is 201 so this is just for the Post we're not overriding the gets we're just overriding the post and then we're gonna eventually return this response first we want to set the access and refresh tokens so access token will be coming from response data get access and then refresh token will be coming from response data gets refresh and then we're going to set the cookies so we've already done this inside of our custom token obtained pair View I'm just going to copy this part go back up and paste it here so we're going to set the axis refresh token in our cookies send back the response and then we're going to have access to them in our cookies so it's as easy as that and the last thing we have to do is just go into our URLs and then from there I'm going to import this custom provider auth view I'm also going to import a regular expression path and then this path is going to be set up like this so I'm going to have a regular expression which is going to be a hat and then o slash and then I'm going to have in Brackets question mark p provider and then backslash capital S Plus and then slash dollar sign so this is going to be o slash e provider slash then this provider will be things like Google oauth 2 Facebook and so on so forth so I'm just going to handle all of those we're going to use our custom provider auth view do a DOT as View and then we're going to have our name of Provider off and there we go we now have that URL set up so now I'm just going to rerun the server and test this out so back inside of here let's retry this again redirect URI must be set so let's set up the redirect URI that's going to be HTTP localhost 3000 slash auth Google so let's send this and there we go we get the authorization URL this is going to be the Google oauth to get or maybe I'll do get authorization URL and I'll save that and I'm going to copy this URL and then back inside of my browser I'm going to paste and then the account that I'm going to log in with is my John to 1357915 account I'm going to click that and I'm going to get redirected back now we're going to end up seeing this because we don't have a nextgs app running right now but we did successfully get redirected to localhost 3000 where that's going to be running we got redirected to this path off Google which are next to us app will eventually handle and then it's going to have this state and code inside of the URL parameters so we're going to grab those and then make the post request not so that's going to work I'm just going to copy everything here inside of these query params and then I can close this up I don't need it anymore and then we can test out that poster Quest so the post request is going to go to localhost 8000 slash API slash o slash the provider of Google oauth 2. slash and now remember we're going to have the content type not of application Json instead we're going to have content type of application slash X www.form URL encoded so then inside of here you can have question mark and then this and we have some extra stuff here so we have the state as a query parameter and we have the code which is right here and its value ends right here and we have all this extra stuff that we don't need so I'm just going to delete that and then inside of our params we can see both our state and code here and then one thing that we need in order for this to work is we need the states to be present in a cookie because it's going to take that value and compare it so I'm going to go open up my cookies I'm gonna add a cookie for state and paste it here now I'm just going to save and there we are so it is not enough to just have this state inside of your query params you also need to have it in a cookie and then with that we can send this request and there we go it worked we got a 201 created we got an access and a refresh token and user so now I can even go retrieve the user and this should all work there we go we successfully logged in using Google oauth 2. I'm just going to save this will be Google oauth to login so now the only other thing that we have to do is also set this up for Facebook oauth so for Facebook auth now I don't need this open anymore actually we'll come back to this side I will leave it open so we're going to want to go is developers facebook.com so you're going to want a Facebook account and then when you go here you're going to sign up to this developers Facebook and then you're going to be able to log in once you log in so I'm already logged in right now and in particular I'm logged in with my John Doe 1357933 gmail.com email so that one is John dalison and then under my apps you can create an app so I'm going to do that I'm going to set up Facebook login click next it's going to be a website I'm not building a game and then you can add your app name which in my case will be full off and then this is my email so now we've hit the dashboard so we're going to now grab those keys that we need so under settings basic next I'm going to grab these two keys so I'm going to grab the app ID I'm going to flip back to my app open up my EnV local paste in inside of the Facebook auth key this key and then I'm going to show the app secret I'm going to copy that go back and paste that in here for the Facebook auth secret key so with that now I can go back for app domains I'm just going to add in localhost here I'm going to save that and then the other thing I have to do is go into use cases and then here for authentication and account creation one thing you have to do is go edit this then by default we don't have permission to grab the email so we have to add that so there we go so now that's ready for testing so I can go back and then we can try things out so what I'm going to do is since I added those environment variables in here I'm just going to restart the server flip on back and then we also have to create a test user so I'm going to go under app roles and this is where we can add testers so I'm going to open up a safari window where you can open up Firefox if you're on Windows doesn't matter I'm just going to navigate to Facebook so facebook.com I'm going to log in with my John Doe 1357915 gmail.com email and then I'm going to go to the profile I'm just going to grab the Facebook ID so that's this part right here so in my case for my account it's going to be John edwards107 so I'm going to flip on back here I'm going to add a tester I'm just going to put in that Facebook ID here and then submit so now it's going to be pending so if I go back so inside of my notifications nothing's going to show up so the place where this actually shows up is if you go to developers.facebook.com so this is now with my other email so this is John Doe 1357915 gmail.com this is the one that I'm requesting so that I can be a tester and then we're going to see under my apps we have a notification so I can click on that you can click on this drop down then we have pending app request and this is where this request is so full auth Dev mode I'm going to accept and that's how you can be a tester so now if I were to refresh that notification is now gone so I can close out of here and I can close out of here so now the next thing I can do is I can come back here I can do a refresh I'll see that pending gone there we go so now this is a tester for this app next step is going to be to send the request so I believe everything is in order to test this out now and then also another thing to note inside of products Facebook login settings right here we have valid oauth redirect Uris now when we were setting things up for Google oauth 2 we put in those valid redirect Uris for Locos 3000 slash auth Google now we don't have to do that here and in fact it's going to complain if we do this sort of thing here and I'll show you exactly why so this is our redirect URI I can put that here I can click save and then I'm going to get this little prompt so localhost redirects are automatically allowed while in development mode only and you don't need to add them here so that's pretty much what it's warning me about so I can just remove it save and that'll get rid of that so by default localhost is already valid and any endpoint for localhost is good so we don't actually have to configure anything there now in production we will we'll have to put like my domain.com Facebook but for development when we're using localhost we don't have to so with that I can now go into Postman I'm gonna copy this open up a new tab paste and this one's going to be for Facebook so I'm gonna put Facebook here and redirect URI it's gonna be like so low cost 8000 API oh Facebook with the redirect URI of low cost 3000 auth Facebook so I'm gonna send this so we get back a response so I can copy this authorized URL I'm gonna flip back into my Safari window open up a new tab and paste this in and there we go we get the submit for log interview some of the permissions Below have not been approved for use so I'm just going to continue as John and there we go so now of course we get so far you can't connect to the server because we're on low cost 3000 and we don't have our next GS app running yet but we did get redirected to the correct place this is where next yes is going to be running and this is where we're going to handle that poster Quest but what we're interested in is right over here in the query params we have this code I'm just going to grab this code and copy everything onwards just gonna copy I'm going to flip back into Postman open up a new tab this is going to be a post request it's going to be localhost 8000 slash Epi slash o slash facebook slash then I'm going to put a question mark and paste so here I have two query params a code and a state that I can see here on the params tab so now we're good except again we need to set that state so the state's cookie just like how we did when we were doing things with Google oauth so I'm going to copy the state value and go into my cookies I'm gonna remove the one that's there add a new one put in States put in the value save and then the last thing you have to do is go into the headers and put in the correct content type content type of application X www form URL encoded and with that we should be good to make this request now I'm going to send it and there we are we got back a response with a 201 created so Facebook oauth 2 has worked on top of that now I can go to retrieve user and I can retrieve and we're gonna have different details here because this user actually has a different last name so we're going to see that if I send this now we see the last name of Edwards so it overwrote what was in there now we still have the same ID so that didn't change but the details are slightly different so there we go now we have Facebook and Google oauth 2 working so I'm just going to save these now this one's gonna be Facebook to get authorization URL and this one's going to be Facebook oauth login all right so only one thing left for us to do and that is to deploy this back-end API and then after we deploy it we have to test it now before we do that there are some things that we need to set up first so in particular one thing we're gonna have to set up is right up here where is it right here our databases so right now we're using SQL Lite but in production we're going to be using postgres and then another thing we have to do is the static URLs and the media URLs so this is what we're using during development but during production we're going to use digital ocean spaces so let's see how we can configure that also I can close out of this now so I'm going to open up this here so this is that guide for digital ocean and Django so there is a section here and this is for setting up the database in production so in particular we're going to need a package and it does mention it further up so right over here we have DJ database URL so this is something we're gonna have to install we're also going to need this Psy cop G2 package so this is a postgresql adapter and then we also need gunicorn and that's going to be for our web server so let's go ahead and install these three packages it's going to open this up stop running and then pip install DJ database URL Psy cop G2 and also unicorn and then there's also going to be one additional thing we need to install so I'm gonna add another pip install and that's going to be for Django Dash storages so this is what's going to allow us to set up using digital ocean spaces in order to have our static files so our static files are going to be stored in there and with Django storages you can also very easily configure this to work with AWS S3 as well but in our case we're going to use digital ocean spaces so with that we have all the packages we need so I'm just going to do a pip freeze requirements txt so that's going to update our requirements txt tab everything it needs and we need to make sure that this has everything we need because in production digitalocean app platform is going to read from that and install our dependencies and if we're missing one things are not going to work I'm going to clear to go back and then something that we also need to do go somewhere in here it has to do with a development mode environment variable that just makes things a little bit easier for us so right here I'm going to copy this line and then I'm going to scroll up and then right below where I have this dot EnV stuff this is where I'm going to paste this in I'm going to remove this OS part so we're going to get an EnV called development mode and then by default it's going to be false so in production we don't have to set this thing it's just going to be false we're going to have false equals true which is going to be a Boolean of false but in our development environment oops in our development environment we're going to have this thing be true so true equals true is going to give us a Boolean of true it's not going to open up my EnV local and at the top I'm going to set this equal to true and I guess I'll put quotes around it since I've been doing that for the other environment variables although you don't have to also I can do that for this one it's just more to make it clear that these are going to be strings and then with that I can now scroll down first thing I'm going to do is the database configuration so if I go back there's going to be that section on setting that up so I'm just going to copy this line here and then I'm going to check if development mode is true if it is we're going to do this and then L if these right here so if this argue V greater than zero and not equal to collect static so if we're not doing click static then we're going to do this here which is grabbing the database URL from our environment variables if that doesn't exist we're going to raise an exception otherwise we're going to set databases equal to this strike here and that's going to configure our default database to be set up in production with postgres so this is an easy way to do it now you can also do it the same way as you have right here you don't have to use this package so I can just set up the engine name then the user host and all that stuff and then I can have a longer configuration here or I can just use this which makes it a little bit easier so now I'm gonna have to switch some things up here so I'm just gonna have get EnV I'm gonna use single quotes and then here I'm also going to get rid of the OS then I have to import this so at the top I'm gonna go right here and I'm gonna import DJ database URL and I'm also going to import sys since that's something that I need in order to access the arguments so if I scroll back down we shouldn't have any other issues here although we do since this has to actually be get the envy and now we shouldn't have any other issues so with that our next step is going to be now the static settings so we're going to want to do something pretty similar so if development mode is true then we're gonna do this otherwise we're going to use our production settings so one thing we're gonna have to do is go into our installed apps and then we installed that Django storages package so then right below say here I'll put in storages so that's going to be the app name for Django storages then I can go back down and then this is where I'm going to have all of those settings for Django storages so let's see what things we have to set up so one of these is for Django storages so this one here and I don't need this anymore so here we have what we have to do so we have to install and then you have Amazon S3 this is where the majority of these settings you're gonna find we also have digital ocean this is going to show you the ones you need to set up for digital ocean so the region name as well as the endpoint but most of the settings we're going to grab from here so first of all this is going to be for media files so if we're using Django version that's greater than 4.2 we want this in our case we are going to grab that paste that here so there we go I'm gonna go back and then this one's going to be first static files now this particular project this setup of course is a little bit Overkill since our only static files we have in our entire project are just the ones for like the admin because we do have that admin panel but in maybe a more production app where you have a lot of features then this could be useful this is more just to show you how to do this more so than it being something that makes sense to have in this project I'm going to copy this now and then below here I'm going to paste that use my single quotes that's going to set up my storages and then I need a couple more settings so if I scroll down we have AWS S3 access key ID as well as the secret access key so I'm going to need those two and then this one's going to be equal to get EnV y I'm just gonna have the exact same name for the environment variable also going to want the secrets key and I'm going to paste that get EnV and it's gonna have the same name and then if we go into the digital ocean settings we're gonna need this here so that's the region name I'm gonna get that from an environment variable which is just going to have the same name then I'm going to need the endpoints and in this case it's going to be an F string I'm going to grab this value here I'm going to paste it here it's just going to be https colon slash slash and then here they also put in this dollar sign you don't want the dollar sign that shouldn't be there so we're going to have the region name which we're grabbing from here Dot digitaloceanspaces.com then we'll go back go into the S3 settings there's a couple other things that we need so if we scroll down we have the storage bucket name that's something we need so I'll put that right below here and then something else we're going to need the AWS S3 object parameters so I'll put that say below here and that's going to be a dictionary with cache control and that's going to have max age equal to 86400 and then 86400 seconds is equivalent to one day then I'm gonna go back I'm gonna grab this AWS default ACL so by default this is none and then options such as public read and private come from here and then use this to set this to public read if not it'll be set to private and we don't want it to be private we want to be able to access what's in the storage so that's going to be equal public Dash read and then after that I'm going to scroll down I'm gonna grab the AWS location and this is going to be static so this is going to be the file in which we have these static files inside of this bucket and then there's only one more thing that we need so if we scroll down we have this Cloud front section where we have an AWS S3 custom domain that we can set up now cloudfront is something specific to AWS although with digital ocean we can still use the same setting so this setting is going to let us set up a custom domain for our CDN so we can configure a CDN on digital ocean spaces and then a CDN is a Content delivery Network and it's going to make fetching any data inside of our digital ocean spaces buckets much faster so that's why we want to use this and we don't have to use a custom domain but we can configure one and it'll just be much nicer to have a custom domain for that so we're going to go ahead and do that so I'll put that setting here and that'll be get EnV and I'll have that right here now all of these environment variables we configured here we don't have to touch those inside of our EnV local because these are all only for production as well as the database URL settings so all of these are production only so we're gonna have to configure those in digitaloceans app platform so with that we should be officially done with writing code for this project and now we just have to have a deployment to be successful so that's going to be our final step first thing I'm going to do I'm just going to deactivate this and I'm going to do a get init I'm going to set up a get repository in here now the next thing I'm going to do is I'm not going to add quite yet so I'm going to navigate to a site called get to ignore.io I'm going to type in Django that's going to generate a git ignore for a Django project I copy everything on there using command a and then just command C and then back in my project I'll make a DOT get ignore file I'm just going to paste all of that in here and then save so now this dot env.local that's something I have to add in here so under the environments that's just going to be an additional thing I add so dot env.local I'm going to save and then that should create that out as well and then I also want to gray out this dot vs code so I'll do that at the bottom and then the last thing I want to do is add a DOT DS store which is just some file that oftentimes gets added with Mac so I just don't want this thing to get committed and with that we are now good to make our initial commits clear do another get status see what we have the git ignore the project folder manage.pi requirements txt and the user's app I'm going to do git add Dot clear do another get status and these are going to be all the files that we add clear once again get commit Dash M initial commit will be my message there we are I'm gonna do it gets Branch Dash a so right now we have a master branch and I'm just going to rename this using git Branch Dash M Main then another gets Branch Dash hey and then we can see that this was renamed to Main and that's just because in GitHub when you create a repository by default that just as you set it to this so I'll just do it that way and then going back I have GitHub open and then I'm going to create a new repository now I'm going to call this full dash off dash API it's going to be public I'm going to create it and then here the steps get a knit also I'm going to add a readme and then we need to commit and then this is that step I just talked about and then we can add the remotes before that I'm just going to quickly add a readme and then I'll do full auth API and then get add dot get commit and add readme and then I'm going to do a git remote add origin just like here get remote at origin then you're going to add your origin now in your case you're probably just gonna do whatever is written here but in my case it's going to be slightly different so in my case I'm going to have get at github.com Dash linked web colon and then this right here so linked web Dash full authapi dot get now the reason for that is because I manage multiple GitHub accounts so inside of my home directory if I go into my DOT SSH and do a cat on config so in particular when I do git at github.com linked web I'm going to have an SSH key that's linked to that GitHub account so right here you can see I have many different repositories so in my case this is just how I manage it so with that I can click enter now in your case you're just going to do git at github.com without this part and then colon and then the path to your Repository the last thing I have to do is get push Dash U origin mean there we go flip back here do a refresh and there's our code so next I'm going to do is go into digitalocean so if you don't have a digital ocean account you're going to want to create one and then one thing that you'll notice I already have a project which I called full auth and I have a domain set up now I set this up ahead of time just because it takes time to have things propagate and end up working so I have a domain in particular onver cell and it's called linked web apptesting.info it's just what I use for testing when I need a domain and then inside of here I set the name servers to be digitalocean name servers so this is how you can get digital ocean to manage your domain so right now if our cell's not managing this right now digital ocean is managing this because the name servers are set to digital oceans then if I click into here I don't really have anything set up other than these NS records which just have digitalocean name servers so that's where I'm at right now so if I ended up doing this right now I'd have to wait like 24 to 48 hours before things get propocated and I can actually use this domain here so the next thing I'm going to do is I'm going to click on this create and then I'm going to create first a digital ocean spaces and then I'm going to set this as the data center and then I'll enable a CDN and then I'm going to put in the bucket name I'm going to call it full off buckets and that's going to be in this project and I'll create this so there we go it's as easy as that to set this up and then we have to set up the CDN we do have the CDN but I guess what I mean is set up a custom domain for the CDN because it's enabled right now so I can click on edit CDN settings and then I can add a new subdomain I'm going to click on that I'm going to select this here and then I'm going to create a new subdomain which is going to be spaces dot my domain so it's going to be spaces.linkedweb apptesting dot info so that's going to be my CDN subdomain and then I'm going to set up a certificate name which I'm going to call full auth certificates and then I'll generate that so there we go and then next we can also set up cores so if we go here click add we can add an origin that we want to cross origin resource sharing so in particular it's going to be our API subdomain which is going to meet the cross origin resource sharing because that's where we have the admin panel which uses the static files so I can do https API dot linked web app testing dot info and then we can just add all of these methods and then here I'll put something like eight six four zero zero and save course configuration and then I can also add some additional course configuration which will be just linked web app testing dot info this is where the front-end app is going to be whoops kind of clicked out of that let's do that again and then for that I'm also just gonna put everything and do eight six four zero zero now in particular our front-end app isn't going to be using any static files from what we have inside of digital ocean spaces although in some apps most likely you will have that happening if you have let's say media files that are in your digital ocean spaces then you're going to want the course configuration set up in that case so I might as well put it there just because it's something you'll commonly do so with that the next I'm going to do is go here and then I'm going to create and then click on apps this is going to be the app platform then here we have GitHub you're going to want to connect your GitHub to your digital ocean and then once you do that this repository you're going to see all of your repositories here and then you can just search for the one you want so I want full auth API Branch Main and then we're gonna have this and auto deploy I'm going to click next and then I'm going to add a resource which is going to be a database and I'm going to click add I'm going to choose the name of DB create and attach click on next then we're going to want to set up our environment variables so I'm going to just set up global environment variables and this part is going to take a little while because we have a lot of environment variables to set up so what I'm going to do I'm just going to shift this over like this I'm going to go here I'm going to grab this put it in this desktop go back and then open this up so we're going to be doing a lot of copy and pasting so I just want to make this a little bit easier so I'll shift this like this something like that so first thing I'm going to want my Django secret key and then for the value I'm just going to grab whatever's here and I'm going to add a little bit to it all right I'm going to add another environment variable and then this one I'm also going to click on this encrypt and then debug by default is going to be false so I have to add that also development mode will be false by default so I have to add that but I will need this and then I'm going to need the SCS Secrets key so this part's a little bit tedious but once it's done then we're good and then the region name and then for domain it's going to differ this is going to be linked swep T testing dot info in my case and then all the cookies secure by default is true so I don't have to touch this setting but I will need the Google auth key that'll need the Google auth secret key and then the Facebook auth key and finally Facebook auth secret key and then I'm going to encrypt this secret key as well as this secret key and then I think also had another secret key somewhere that was for SES I'm also going to encrypt this one I'm gonna go back down next I'm gonna have my redirect urls in this case I'm going to have https colon slash slash linked web app testing dot info slash off slash Google comma and then again https colon slash slash linked web app testing dot info slash auth slash Facebook so these are going to be comma separated and then we're going to have a bunch of additional environment variables we also have to set up so we've got where's the database settings there we are so we're gonna have database URL that we have to set up and then if we open uh or actually we're already in here I think this is where we have this documentation and then there is a note on database URL on how we set this up should be at the bottom because here we have a deployment step for this setup here so one thing we have to do is in run command we'll have to set this up but we'll do that a little later and then here we have database URL and this is how you set the value so we're going to do dollar sign curly brace the name of our database which was DB and then dot database URL just like how they have here I'm just going to copy this I'm going to go back to my digital ocean settings here I'm just going to paste that in here so that's going to be the value create another environment variable and then here I'm gonna have a couple so that was in my static settings so I have this AWS S3 access key also have this secret key I'm just going to add the keys first and then I'll do the values I'm gonna have the storage buckets name this I can fill out right now I called mine full auth buckets I'm gonna have the region name this in my case is NYC three and let's see what else I need custom domain so that one's going to be spaces dot linked web app testing dot info that's what I set up and that should be so now I just have to grab the two values here so how do we get those so now what I'm going to do is I'm just going to bring this back to how it was and then I'm going to make this full screen again and then I'm going to scroll down then under API I'm going to open up a new tab to open this API then here we have spaces keys so I'm going to go here I'm going to generate a new key I'm going to call this full auth key I'm gonna create that and then I can copy this that's going to be the value for the access key ID and then this will be the secret so I'm going to paste that here and I'm also going to encrypt that so now we should have all of our settings here unless I missed something which I very well might have oftentimes things do go wrong during deployment but who knows maybe this time it won't and then also this right here you can see the region name and also the bucket name so full of buckets nyc3 so you can get those values here so everything should now be good to go so I'm going to save this I'm going to click next and also we have one environment variable here and that is actually this database URL so we don't actually have to set it up globally so I'll just remove that click save so now we have 16 environment variables and then here we have this one for the database I'm going to click next and then let's see what else we can edit here so we can't edit the runtime yet so we're gonna have to do that later so this is what we got for now so I'm going to create these resources and actually I did forget to do one thing and that was this plan so actually what I want to do is use a basic plan I'm going to save that and downgrade the plan so I forgot to do that but you can always do it later so it's no big deal and then we can go into commands go into the Run command and then you're going to put in your project name in my case full underscore auth.wsgi and you have the same exact thing showing in here as well I think it was just a little further up so there it is so unicorn worker temp directory Dev shm the name of your project.wsgi so that's the same thing we have here so I'm going to save that and that should be everything so from there I can go to the build logs and just wait for this to finish okay and there we go we have our build and deployment successful however we're not quite done also while this was going on I did remember two environment variables that I did miss so I'm also gonna have to add those in so it's pretty easy to do thankfully so you can just go into here and just add whatever other environment variables you need so the ones that I missed in particular if I scroll up we do need our allowed hosts setting and then that one is going to be API dot linked web app testing dot info then there's going to be one more that we need so if we scroll down so at the bottom we set up this course allowed Origins and here we're gonna have whatever Origins are allowed to make requests to this API so I'm going to go back I'm going to paste this setting in and the origin we want is https colon slash slash linked web app testing dot info so that's going to be where our front end eventually gets deployed so I can save that and then that is going to trigger another deployment so I'm just going to wait for that to finish and then the last thing we're gonna have to do is also set up the custom domain because right now we added that API linked web apptesting dot info although we didn't configure that so right now things wouldn't really work so we have to set that up as well but first i'm just going to let this do its thing and then I'll do that after and there we go we ended up successfully building and deploying so now what I can do is I can go to my settings I can go to domains and I can add a domain this is going to be linked web app testing dot info then I'm going to say we manage your domain I'm going to add it and that's pretty much it so now it's going to go through this once again and then what I'm going to do is I'm going to quickly go into this domains just to show you something so right now what we had previously was just these NS records but we see that additional things did end up getting added here and also I did make a slight blender I just realized I meant to do the sub domain here so I actually will have to go back and edit that so let's actually do that I'm gonna go into domains and then this one I'm gonna actually end up removing later so this configuration might take quite a while so I'm just gonna add API dot linked web app testing dot info we manage your domain and I'm gonna add that that's going to run another deployment but then in my settings so it looks like this one finished so I'm gonna now remove it since I don't want that one that was a slight error on my end so now we're going to configure this one instead because we do want our API on this subdomain so with that we should now be able to go here go to domains and there we go we have a c name now one thing we don't have is our digitalocean spaces set up here that's one thing I expected to see but for some reason it's not here so maybe there was something I forgot to configure so let's go back also we see these static files are here so that's good so we set up the CDN and it seems that the subdomain okay so we have to select it here and then click save so now that should be good so that's something I forgot to do so with that we should now be able to go back here and then we can click on the domains and now we have everything set up so perfect so now everything should work although there is one final step and that's actually outlined in this document as well so once you go through everything ah here it is so you're going to want to do a python manage.pi migrates and also create super user if you want to create a super user which in my case I do and then also in particular I want to do this so I can test if these static files are working in production so now I can just go into apps go into the console and then in here we have our project so now we can do a python manage dot Pi migrate there we go that ran all of our migrations and finally python manage.pi create super user for the email I'll do admin at linked web app testing dot info first name will be Brian last name rickich set my password and there we go we have a super user created so now we can test things out so I'm going to go to API dot linked web app testing dot info slash admin slash and seems something went wrong and it turns out was actually one of the settings that I ended up configuring wrong of course I put in allowed hosts as my environment variable when it should have been Django allowed hosts figured it might have something to do with that so I'm gonna have to edit this and change it to be Django allowed hosts save that so that's going to trigger a rebuild and redeploy and after that hopefully there's no other error now it is very difficult to go through all this deployment process without a single issue happening just because there are so many steps and any little typo can just make things go wrong but anyway it's gonna wait for this to rebuild redeploy and then we'll test things out and there we go our build in deployment finished up so now the moment of truth I'm gonna refresh this page and it's loading so let's see what happens and there we go we have our Django admin panel and we see CSS styling which means our static files are working now in production now let's test out logging in so admin at linked web app testing dot info with my password and there we go we can log into the admin panel now we didn't really configure anything inside of the admin panel there's nothing that we're really managing we didn't even register the users to manage them but all I really wanted to see was that the static files that we configured for production are working and that we can actually log in here have all the styling working so that's really the main thing I want not really configuring the admin panel so with that you can just log out so we tested that out so the final thing we have to do now is just test out our production endpoints so I'm gonna flip back here and now we can send this request and that's going to be for creating our user so I'm going to send this off and there we go our user was created awesome and I'm just going to copy this production endpoint because I'm going to be using that I'm going to go to user activation I'm going to paste it in here and then I'm just going to want to edit these values because I'm about to get a link in my email so here if I refresh we got an email account activation on full auth you can also see right here this is our production domain so this is where eventually we're gonna have our next JS application hosted on and then that's going to handle this endpoint here and do the post request using the uid and token but for now we don't have that we just have Postman so that's how we're gonna hit this activation endpoint so I'm just gonna paste in here I'm gonna grab the token I'm gonna cut it remove the Slash and put the token in here then before I send this off I also want to test out the user create just to make sure that it fails and this is also going to be with my secure password because inside abuser create that's what we have here and then I'm also going to grab the production domain put that in here save send the request off it should fail there we go and now if I send this off there we go 204 no content so now if I remake this request there we go access and refresh token awesome and then another thing is that in my cookies we're going to notice we have the cookies set up we have the domain set which is going to be API dot my domain we have the path HTTP only and secure is true so these are getting sent through an SSL connection so awesome we got that now we can also hit R refresh and it's also super easy now because we have to go into the body and add a refresh token we can just send the request off and of course I forgot to adjust the production domain I'm gonna put that here and there we go back a new access token which of course you can grab it from the data but also in our cookies it was updated now and we got to verify which we can also hit there we go 200 okay and we can also hit our retrieve user endpoints so we have to be authorized to hit this and there we go we get our user details we can also test out resetting our password in production so this is the confirm one I want to do this one first I'm going to send this request should receive an email there it is and here we have the production URL so what I want for now is just the uid and token and then I'm going to go to the confirm one go into the body paste the contents there I'm going to grab the token cut that remove the Slash and put the token here I'm going to reset the password to this right here just like we did during development I'm gonna send this oh I forgot to update to the production endpoint so I'm going to update that save and send there we go 204 no content so that should have worked which means that right now with my create endpoint if I send this off it should fail there we go 401 unauthorized but if I update the password to what I just reset it to this should now work and it does we've got a 200 okay perfect and then we can also test out the log out paste in the production URL log out there we go so now if I try to hit my verify that should fail there we go we have no token and then that leaves us with only our oauth and points left so that's the last thing we have to test out and then for those we are going to have to configure some things so first I'm gonna have to go into the consolecloud google.com I'm gonna have to go into the oauth 2.0 client IDs and I'm gonna have to add a URI for both of these so for the origin I'm going to need https linked web app testing dot info and then for the authorized redirect Uris I'm going to need https linked web app testing dot info slash auth slash Google so this is going to allow this to work in production and then I'm also going to have to go into here so this is in my developer Facebook login app I'm gonna have to go into my valid oauth redirect Uris here I'm going to add https link to web apptesting.info slash auth Facebook that's my valid or3 direct URI I'm going to save those changes and then under basic settings another thing I can do is under app domains I can add linked web app testing dot info and then also under advanced another thing you can do is also add domain manager and you can also add here as well so I'm going to do https link to web app testing dot info and that'll be an exact match and I'll save those changes so there we go right now everything should be set up for us to test so let's try it out copy the production URL I'm going to close up some of these things and first let's test out Google oauth 2. paste this in here with the redirect URL send that off and yes I need to actually change this here to also be the production version so that's going to be https linked web app testing dot info slash Google so we gotta make sure we have that correct as well I'm gonna send that and there we go authorization URL so now I can just copy this and then in a new tab I'm going to paste that enter I'm going to use my John Doe one three five seven nine one five accounts and there we go we are now redirected to linkedweb apptesting dot info slash Google which is perfect of course we don't have our front end running here quite yet but eventually we will and this is what's going to handle that post request but we can still test out that poster Quest so I'm going to grab with these query parameters these states and the code so I'm just going to copy everything that's here go back to postman I'm gonna open up the Google oauth 2 login and then I'm just going to delete what's here I'm gonna do question mark paste and then there's a couple things I don't need that are here so I think all of these so there we go we just have state and code now and the other thing I'm gonna have to do is copy the state let's go to my cookies remove the one that was there add a new one it's going to be this state value and then I'm gonna have to update this to the production URL and with that we should be good so let's send this request there we go we successfully created an account using Google oauth 2. and that was in production so the final thing we're going to test is now Facebook oauth 2 in production so first I'm going to go here paste this and then also I'm going to update the redirect URI and actually I'm going to test it also without doing that so there we go we get that same error as before so let's update this and then we'll send this off and now we get the authorization URL so I'm going to copy that and then in this case I'm going to go into this window here where I have John Edwards so that's my test Facebook account paste this in here and then if we take a look of course we don't have anything running here but we are brought to the correct Place linked to abouttesting.info slash off Facebook which is where our next JS app will run in production and handle this post request but what we can do right now is just grab everything in the query parameters and just copy that and then I can close this go back to postman open up Facebook oauth 2 login and then I'm just gonna delete everything here paste what I just copied and I'm just going to remove some of these things I don't need and only have my code and state in here then I'm gonna have to update this to the production URL foreign and the final thing I have to do is grab the state value go into my cookies I'll delete the one that's there create a new one paste save and now when we hit this it should work and it does awesome now we also have Facebook oauth 2 working in production so that is super cool so now our backend API is officially deployed and working so with that if you wanted this to be a little bit more production ready then of course what you can do is with your AWS SCS push that to a production version because right now also I'm probably going to be logged out well maybe not so here we have by default it's in the sandbox environment but you'd want to request production access so that's one thing you'd want to do another thing is you'd want to go live with your developers facebook.com and then with your google.com you'd probably just want to create a different set of oauth 2.0 client IDs and use those for production and then I'd say actually there's one more thing you'd also have to go to your oauth consent screen and also publish your app because right now it's in testing but you'd want to publish it and then you would be production ready so that's pretty much the only things you'd have to do in terms of the Google and Facebook oauth 2 and then you'd be good to go so there we go that's literally our entire app now deployed with digitalocean app platform and digital ocean spaces so I'm just going to show one final little thing and this is going to be with our digital ocean spaces and it's not something that would come into play with our app right now but if you had media files they would now go inside of the static folder so that's gonna be the final thing I'm going to show we're not going to test it because we don't really have a way to test it but I'm just going to show you how to do it just because it's a common thing you might do so what you're gonna do in order to have this Behavior so where we have our static settings which is right here right now we have this AWS location we're going to add another setting AWS media location which is going to be media now this right here is not a setting that is part of the Django spaces package it's just something that we have that we're going to use and we're gonna set up a custom class which is going to inherit s3boto 3 storage and then we're going to apply it here and it's going to use media instead of static as the folder that's going to be the final thing we do so what I'm going to do is I'm going to create a file called custom underscore storages dot pi now ideally I would like to have this file be and let's say the project folder except the only problem is then you can't create a path to it so I think the best place is just in the root for this file and then I'm just going to copy this paste it here and then from storage's back ends s 3.03 I'm going to import S3 Moto 3 storage I'm going to create a class which is custom S3 photo 3 storage just going to inherit this it's going to set location equal to that setting we made so I'm going to do from django.com import settings and settings dots AWS media location which is what we called it just want to make sure these match up perfect and there we go so that's literally all you'd have to do and then just you'd want to set this to be your custom storages and then custom s3.03 storage so this would be the path to it now if we placed this inside of the project we'd have no way to do like custom storages dot this of course we could also put this inside of like an app folder and then do like users dot customstorages dot this but there's not really an app where this file really fits in it so I think the best place is the root so that's just where I put it and then with that I'm just gonna get to add commits and then just get push origin name this is also going to Showcase something kind of cool actually so it's kind of good that I also left this so if we go back we're going to notice is I just push the main and that's going to trigger an auto deploy so there we go we see it's now building and it's going to deploy and there's nothing that I need to touch it's just going to be automated so anyway that's going to be everything for the video I hope you enjoyed this video If you enjoyed this kind of content please leave a like on the video subscribe if you want to see more of this kind of content you can also hit that notification Bell if you don't have enough notifications in your life and that'll be everything for this video I'll see you in the next one
Info
Channel: Bryan Brkic
Views: 15,291
Rating: undefined out of 5
Keywords: website development, web development, app development, mobile app, mobile app development, django, REST API, django rest framework, react, node, express, mongodb, postgresql, development, websites, apps, django react app, django react, full stack, mern stack, node react, redux
Id: 2pZmxh8Tf78
Channel Id: undefined
Length: 206min 36sec (12396 seconds)
Published: Mon Jun 05 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.