Django Email Verification in Registration. Python Django Web Framework Course. #28

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys welcome back so in the past videos we have been able to sign up a user and we can log them in so in this video i'm going to be showing you how you can restrict access to people who have emails that are verified so you'll notice that most of the websites these days or most of the apps they will require users to first verify their emails before they can really access services on the site so that's what we're going to be doing now so every time a user enters here their credentials and they submit we want to send them account with an account verification email for which they can click from their email and we bring them back to application and activate their their their account and yeah so it's gonna be fun let's go ahead and build it okay so we start off where we have the user mode so our user model actually inhales from abstract user so abstract user is the best model that django authentication uses so by default they don't have the is verified or a way to know if the user's email is verified so now since in our custom model we are inheriting from it we can add to it we are going to add another attribute here code is email verified okay so it's going to be a boolean field by default it's going to be false so now that we have made a change here we need to basically migrate we need basically migrate these changes so our database knows about them so we want to do manage.py make migrations okay so that's gonna add that is verified then now we want to migrate to make sure everything is synced properly okay so now that we have these changes we want to change a few things about the way we are basically logging in a user so you will note that if you go to authentication and then registration so i've got the views then the registration again you see that every time they create an account we basically create it and then we tell them to log in and that's okay but now on the login we want to go to where we authenticate the user so here after authenticate we want to check if their email is verified so we can do if user but is email verified so if it's verified then we want to log them in but if it's not so here one check if not so if it's not verified then we want to tell them hey you didn't verify your email please verify again so what i want to do is i'm going to go over here so over here we can send them and we can return a message something like email is not verified email inbox ensures check the spam tool if you will so every time this email is not verified it may not be verified for specific for some reasons one of those might be because a user maybe didn't click the link or they clicked the link at a point when it was expired so we need to provide a way for them to to request that email so at this point in time we have the user so in here we have the users if the user authenticates properly we have their email here so what you do in that case is you would send them to a template when where you can have a button let's say a button to resend email and then when they click it then you receive the email but for now let's just focus on basically sending them the first email and also activating them so here you see when they are not activated we are not going to be logging them in so now we need the word send them the activation email now to send an activation email we're going to go here in the registration so that's going to be here so before we redirect them we want to send them an email so i'm going to put the function called send activation email and uh we need to create it so i'm gonna go up here so i'm gonna pass it the user right and also the request because we're going to need this so let's go up here and create this function so on here i'm going to have a dev send activation email now it's going to take in the user like so then the request so here what we want to do is we want to basically have a few things one of the few things we are going to need to have an email subject and also we're going to have like the message you want to tell a user like hey please use this link to activate your account so also we need a way to have them redirect to the same website that we sent the email from and go to the login or go to our activation route so over here we need to first have a way of knowing which domain we are running on so i'm going to have a variable called current site so to get the current site the application is being served on we need to use a utility from django's sites so from django contrib load sites dot shortcuts i believe yeah import get current site okay so here we need to do get current site so get current site takes in the the request so you have the request there so that's going to give us something like localhost or if we're on some domain it gives us some domain.com or whatever the domain will be okay so now that we have the site we need to construct a subject so here we can have email subject so this can be something like hey like activate your account so now we need to construct the email we are going to send them so the email body so here what i want to do is i want to set up email body so for the body we're going to be using a utility code render to string now basically what render to string does is it takes a template like an html template and then it can pass dynamic values to it so let's import render to string here so yeah import render to string okay so we'll be creating that template in a few but moving on over here we want to say render to string so we need to create that template so over here i'm going to have an authentication then i'm going to call it activate.html so we need to send some things to it so over here we're going to have a context but for that context in that template you're going to need to have access to like the user so we can like say the username like hello hello alex or whoever it would be so now we have the user there so also we need to have the domain because we want to construct a link that they can use so you can pass current site there all right so then the other thing will be so guys if you think about it we are going to be sending emails from one server to the other we will also be using an smtp server so other things so for us to be able to transfer that information across different servers we need a way to ensure compatibility between those those systems that we'll be interacting with and also we need to make sure that our information is secure so here we will have a uid so the uid will be basically the users the user's id but we are going to need to encrypt it and also have it in a format that can be understood by other systems so over here we are going to also have some utilities so we're going to go here from django http and input some things okay so once we have this we're also going to need to have to encode the user's token so whenever we send them a link it's going to have that token so we need a way to encode those so we're going to import some utilities also from django so we're going to say from django.details dots encoding import we're going to import first bytes first str and also first text okay so this is going to make sure that whenever we are sending out data from our application we basically encode it into byte format and whenever we are getting it back we can now use first str or first text to read it back into native python objects so also i'm going to have a to import this code here this error code here so we can be able to use this okay so moving on so here where we need to pass the uid like i said we don't need to send our exact id of the user something like id1 or id2 we need to encode it in base64 format so people don't like start to guess it in the url or something so here what you can do is we need to do url safe base64 in code like this then what we want to do there is we want to save first bytes so first bytes will be transferring the the the id so you know id is an integer so what this will do is it's going to convert it into byte format so let's press user dot speaker so that way it can be safely transferred over different systems okay so here let's put a comma we also need the token so the token will be that string token string we sent to the user that we used to identify if it was generated from our server or if it is still valid or it expired those kinds of things so to get the token so django has a specific utility to reset passwords but they don't have utilities to verify users emails or they don't have a way for us to be able to generate tokens that we can use like one time so what i'm going to do over here i'm going to create a tools file and we're going to be building on that password generator class that django uses and after you like manage passwords so we're going to be using it here to create a utility that we can use to cr to make a token that can be used one time so what we want to do here is we want to import that class so it's from django you choose so we're gonna do it's actually django contrib both tokens import password generator okay so here we're going to create our own class so we're going to call it password generator then we're going to inherit from password generator so to get everything that password generator has and then we are going to be overriding if a function called make hash value so here gonna say make hash variant so you see that it takes in the the user and then the timestamp now the way this make hash value works is basically it gives a way for us to create that token and have a way of verifying if that token had changed depending on the return of this hash value so to be able to create a hash we're going to need to use some utilities to make sure that the hash we create is basically compatible so now we're going to need to create this hash so this make hash value we need it to return a value that whenever compared again we'll tell that it had changed so how do we tell that it had changed so the cases for those will be if a user let's say has already activated we can return here a value that every time the user activates it changes so over here we're going to return a string so the string is going to be we're going to be using these utilities so we're going to say str then we're going to turn the user dot pk then i'm going to be adding sdr again here here we can pass the time sample so and most importantly here we are going to be concatenating their user dot is email verified maybe that's how we called it now every time this hash changes then that means that whenever we are now comparing again the hashes for this user this will have changed and we can know that oh this was used before and hey you shouldn't be using it again you'll notice that now we are using str str to basically turn this into strings but this is a building so the best way to actually make this a hash string barrier is to use a utility called six so i'm gonna save i'm gonna put the server here and install six actually maximize this and install six i'm gonna do pip install six okay so here we can do input 6 now here instead of us doing str then let me do this then we're going to be doing six then we're going to do text type and then it's going to be that so similar this is gonna be six text type the timestamp then this is also gonna be six then text type then the email verify so now we need to return this now we're gonna do this return like this let me actually maximize this so over here we need to import that utility so i'm gonna save from utils import password actually it's called token generator you see how we called it so i should be talking i don't password generator so token generator okay so over here i'm going to create a function it's going to be called generate token so this is going to be equal to password in token generator okay like this so now we can use generate token to generate the token basically so you can say from youtube generate token so now if we go back to what we are doing here we can now say generate token then whenever we call generate token dot make token so make token text in the user want to make the token form so we can pass the user there so now we need to create this activate template so i'm gonna go to our templates so that's gonna be here authentication let's create activate.html so first i'm going to load this tab called autoescape so escape then we'll turn it off so we don't want django to escape any characters we'll put in here but we need to end it also all right so in here now we can construct our message so we want to say hi then the username so the username since we are passing the user to this template so that's going to be here you can just do user.username and the user the username then we tell them please use the link below to verify your account okay so now let's create the link so the link we're going to start off with http because we don't have the we didn't get the protocol from the view but you can also get the protocol and also pass it here but for most of the of the sites if they have https then it's going to be redirecting actually all https to https so it's gonna still gonna be fine okay so here we need to pass the domain since we're already passing it so we can say domain then here so remember whenever they click on the link we need to take them to a view where we can verify from so i'm going to put here the view it's going to be something like our domain slash auth slash activate and then the url is going to have two things it's going to have the encoded user id and also the token we generate for them so here we can have our number our regular syntax then we're gonna have url so the url we are going to create that view and we're gonna give it a name called activate so also it's gonna be taking in two parameters so in the view you'll note that we are passing uid and then the token so here i can get a uid here like this so that's going to be equal to the id so since it's encoded i'm going to say b64 here because that's what it is so also here we can pass the token so the token is going to be the token we generate okay so now this looks good so let's go ahead and create the view so i'm gonna go to views.py and the view is gonna look it's gonna be simple so down here you can have def activate user so it's gonna take in request and then we know it's gonna take in two other things so it's gonna take in the encoded user id so it's gonna be id b64 then it's gonna take in our token okay so here what we want to do is we want to be getting the user id okay from the from the encoded one so i'm going to have a try accept broke here so i'm going to be accepting it's exception as there's e i didn't try except is while trying to decode this token we might get some errors so we don't want the application to crash when that happens so we're going to create an id so the idea we're going to try to now get it from the encoded one so remember how we did first bytes when we were turning the id into bytes so you can save first text so first text we are going to be passing the decoded version of uh of the over id so pass this then we pass uid b6 the form so this should now return for us or easily like one or two three okay so now the next thing we will do is try to get the user so we're gonna say user equals user so that's the user model objects get so get it's gonna be pk equals this id so here what you can do so here if we have an error then of course something would have gone wrong so we'll set the user here to now to none so down here i'm going to make a simple check so we're going to check if we have the user and also i'm going to check if the token was not used before so check if the token was not used before we do i think we called it generate token generate token and then we call check token on it so check token takes in the user the past user there then the token we want to check so we already have the token so if this is true so that means this this is valid so want to guide and now activate the user so now that through the user with the user dot is email verified then we set it to true and then we need to save the user so it's a user dot save okay so now we can tell them your account was activated you can go ahead and log in so let's do messages that add message it's going to be successful then we say email verify you can log in then we can now return them to the login so we can say return redirect so we can say reverse for login okay so otherwise if something goes wrong then we want to maybe tell them to request the regression email so over here i'm going just return first return render so we're gonna be rendering just a template that says something went wrong request a new one so the templates let's have let's have it in auth so it's gonna be authentication then you say activate failed html okay so when it fails we need to pass the user if if the user is there so we can have a context here so to pass the user you can do user then we pass the user so we can check if that user is there in the template and maybe tell them to reset to request a new one so we need to add this to our url py so we're going to go over here and also create this so path so here is going to be activate user and by the way the user will not see it so for us when they come to the site we will check them and then redirect them so it's gonna be views dot activate user so the the name remember in our in our template we said it should be called activate over here so that's why we have this here gonna be activate user fine okay so now stuff are looking good but you might be asking yourself okay how are we going to send the email how is it gonna go so first send the email over here we're going to be using a class called email message so i'm going to import it from django.com so from django.com. import email message so now over here once we've created our email what we want to do is now say email message so we want to give it things like the subject so you can say subject equals the subject email subject then we need to pass it the message so we can say the message is going to be the body here so you can say body because the email body then the next thing that you want to pass is if you look here we need to pass a from email so from email is the email they tell the user that this may be something like accounts at ourapp.com so someone who is sending that email so we're gonna have a setting so let me so we're gonna have a setting in our settings py that's gonna be the from email so what you can do over here is let's import settings here so we can access what's in the settings so from jungle conf import settings so now here we'll be creating it we can say settings though it's from email from email email from user so this is gonna of course be from email it's gonna be like that save it then we need to now specify the email of the user that we want to send the email to so to spread the email it has to be a list so we're going to use the syntax here and pass the user email so user image is going to be in user.email like this so let's make sure that here we pass the two key so now that we have this we need to send it so yeah i'm going to create a variable called this so down here we say email dot send okay and save so now if we run back our server you already know that we have not set up how to send the name from the user so django makes this one really easy we just need to tell it about a few things now the things that it requires us to tell it about is we're going to go to our settings.py and first off remember when you set up the email from user so we're going to go to settings.py so that's here settings py okay email config so email from user so for the email from user this can be anything but i'm going to be using gmail to send out emails so gmail provides us an smtp service where you can like log into an email and then perform things like sending an email when you're not using the gmail applications but rather through the smtp so i'm gonna bring in these other email settings that django needs so one of them is gonna be the email host the email host user the email host password and whether we should do tls or not and then the port for the email so over here what we want is here i'm going to be so over here you'll notice that i'm putting these values from the environment so for now i'm going to i'm not going to be putting them from the environment but i want to say that whenever you are doing this make sure you're putting them from the environment now we already have it with m file so you can maybe come over here and export them so you can say export let's say from email from email user say something like stuck up academy gmail dot com so with the dot mv you actually don't need to specify this it's gonna be passed to a string so so now over here we can come and say okay our host user is gonna be os environ get from user okay so the host we are going to be using the the s the gmail smtp service so the host now is going to be i'm going to be add coding it here but feel free to move them the environment before you push to github that's what i'm going to do too so here you do smtp gmail.com then the host user is going to be my user so this is so whenever you have a gmail account that is what you want to use here so i'm going to be using the same account you show me setup and then for the password this would be the password of your gmail account your current password of your gmail account so you can use this only when you don't have two-factor authentication set up on on your google account so if you have then you can look into how to use app passwords or you can create this another sample ima sample google account just to handle the the testing here so here what i want to do now is so that use dls will be true and then the port is five eight seven so this this is the setting you're always gonna have if you're going to be using gmail so i need to set up my password so over here in my dot f i'm going to now export the password so the password is gonna be anything so i'm not gonna be showing you guys what that is but it's gonna be anything feel free to enter your password over there and now when we make changes to the environment we need to update our application by sourcing in the environment again and then restarting the the application so now here everything is set up correctly i'm just gonna pause and make my and make changes to the environment to make sure that my password is correct and it doesn't fail to work okay so i'm going to hit to change my dot m to use a real password and now we can go ahead test out the app so the app is still up and running so we're gonna open this so this is gonna open up we're gonna go to create account now i'm gonna sign up a user that we have not signed up so when you click submit oh this email is taken let's use this one so when you click submit is that now we are getting some issues so you notice that up front we are getting reverse for this is not found and you see that the argument we are passing in is uid b64 and then the token so that means that in the urls.py urls.py that's gonna be here we need to be passing this so over here we need to make sure we are expecting them so we expect this we are expecting this and also the token so make sure you have those okay so this should also be a placeholder so we're gonna do token there and yeah so now if it restarts and we come back over here let's go try sign up another user let me use the other stack up academy email password password submit oh image again so it looks like all my accounts are taken so i'm going to post the server and first date all these users so we're going to open up the django share so jungle gives us a way to really interact with the database or application in the terminal so we do that through the share so so now i want to delete all the existing users now we can delete those by using the model so i'm going to import the model so from authentication go to modules imports user so you can see user objects should be dot or user objects all then i want to delete all of them so you can say delete okay so that's gonna go and go ahead and delete for so also it deletes it deletes the to-do's that those users had because we have a cascade on delete so now to exit you can hit ctrl d and then let's run back our server okay so here if we try it again send a password password click submit and uh let's do it for it okay so when it's done you see that we get account created you can now log in that's because we need to change a message when we send an email but what i want to show you is i want to open up my gmail account here and when it opens up you see that now we have this email here so you see that you so you see that we now have this email here in my inbox so this email is telling us hi this is the username i just added and it's telling us we can use this thing to activate so when i click on this link notice that we we are brought here we are told that our email is activated and now we can log in that means that everything is working but now when i click it again is that now things fail so they are failing because it is looking out for activate failed and this means that our link can only be used once since we are trying to use it twice so on that in that view or on that template which let's create it so application doesn't break like it's doing so on this template we can say maybe something like let's put a paragraph here and say something went wrong something went wrong with your link okay so if you have any cases here you can maybe tell them to to request a new one or you can do anything you want here okay so if we refresh you see that now this is the template that will show but the account gets activated at first okay so to test it out first of a few notes that when we finish we didn't get the message that we have they sent us an email so we want to go to our views so on the sign up after we send an email actually this should be not action but activation let me change it activation so whenever we send an email one tell them we sent you an email to verify your account we want to actually test it out properly so i'm going to open up the share and the import user so from authentication modules import user so here we say user objects or delete delete like this okay so now stop the server let's run it again so now if we come here let's go to the register and i'm going to enter a user so here can be password so you can do the same user it's going to be this now sign up and you see we get this we sent you an email so if we come here if we if we came here in the share and try to verify if the user's email is verified so i'm gonna go to python manage the pure share let's import the user again so from authentication [Music] models imports user user so we say user objects right now we know we only have one user so if we said all it's gonna return it should be user objects not objects so objects so see this is one now so we can check is email verified i believe since the user it's since the user so this returns an acquires an array with query sets so let's pick the first and run that so you see that now it is false but now let's check our inbox so i'm gonna do this and run back the server so if we come to our email again you said now we have this new email and uh when i click it is that now it's verified so to verify that it did actually verify we're gonna do shell again just import our authentication mode again so from authentication models import user so now to check the user we can say user objects objects or by the way here you can do first since we have your one user and we know what you can do first then you see that is the user now we can check his email verified and you can see that now it is verified meaning that now this way a user can continue to use the application they can log in so one thing that i want to show you guys is uh what so one thing that i've noticed is so one thing that i've noticed is whenever we send an email here so let's try something fresh here uh let me just put that down because this one i'm not following it so whenever we put an email here and try to submit it you see that it takes a while to to return to the user so the user doesn't know what's going on it is actually loading for a long time that's because it is sending out an email now we really don't want to make a user wait uh that long because what are we really doing sending an email is something we can do in the background and tell a user that hey we sent you an email and then they can wait for it okay so to speed it up a bit i'm gonna have to come over here and create a thread so with python we can use threads so threads allow us to run different processes in one program so that means that our application now can focus on like interacting with the user while some threads handle things like sending an email so here i'm going to set up a class i'm going to call it email thread so this will inherit from threading the thread okay so over here we need to have a constructor so in the constructor it's going to be under init so the constructor is going to be taking in self of course then we'll be passing basically the message we want to send so here you can pass email so down here we can we can initialize this email to the one that the user passes then we want to do threading thread init self okay so to send the mail we need to implement a function called run so run text himself of course and now here we can run a task so we want to send out this image and say self.this email then we want to run send on it so it should be just send now we need to create an instance of this class and pass the email we want it to send basically so we should be importing threading i was hoping we are so important link here so instead of us sending it here we can upload it to the to the other thread up there so here we need to initialize it so you can say email thread then you see it has to be instantiated using the email we want to send so we want to pass it and then we want to call start on it so threads when you call start it's gonna come and run what's in this in the run so remember email now has is an instance of the email message and it has the send property on it so it's gonna now come here and call send okay so now if you come back to application so i'm gonna come back here so now i'm going to be using a rear image make sure it is still working so here let me use this so for the email i'm going to use this very same email so if you submit you see that now it is instant now if i go to my my account so i'm gonna go to my account you'll see that yeah our email has arrived and uh yeah so if we click it our account gets activated so here we can continue we can go ahead and log in okay so that's gonna do it for the video so if you guys ever get an issue sending that email make sure you have insecure apps allowed in your google account so to do that you want to go to your google account so here i'm gonna go to manage my account and uh then you want to go to security on security you want to look for less secure apps so unless secure apps you want to turn this on so if we turn this off things will fail but make sure you turn it on and your accountant is two-factor authentication if it does please look into how to use a password to send out the email so yeah so i hope you found this tutorial helpful if you did give it a thumbs up don't forget to subscribe and i'll talk to you soon
Info
Channel: Cryce Truly
Views: 7,308
Rating: undefined out of 5
Keywords:
Id: Rbkc-0rqSw8
Channel Id: undefined
Length: 36min 18sec (2178 seconds)
Published: Fri Apr 09 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.