This video demonstrates implementing JWT (JSON Web Token) authentication in FastAPI, covering three key endpoints: (1) user registration with email/password validation and password hashing using bcrypt, (2) token generation endpoint that authenticates users and returns JWT tokens for authenticated access, and (3) a 'me' endpoint that retrieves the current authenticated user by decoding the JWT token and querying the database. The implementation uses SQLAlchemy for database operations, passlib for password hashing, and PyJWT for token encoding/decoding, with proper error handling for invalid credentials and duplicate users.
FastAPI User JWT Authentication: Create Token and Retrieve Current User
Added:[Music] what's going on you guys so for this video we'll be continuing from where we left off in the last one and in this one we will create our endpoints for creating a user for uh creating a token and that will be used for jwt token like authentication and also retrieving the current user that signed in so to begin with let's jump into our main.py file and in there let's first make the necessary imports so we can say the first thing that we need is the fast api library so import fast api is fast api we can also import fast api dot security as we'll need that later on and we can just call this security and that will be for the oauth uh to um request form that we'll need and but yeah you'll see that later on uh import sql alchemy dot orm as underscore orm and we can also import services file as services and schemas as underscore just like that we can create the app so app equals fast ap underscore fast api dot fast api and then for the first endpoint we'll do create user so that will be a post and we'll say api users and this will be asynchronous and we can just say create underscore user this will take in two parameters the first one is the user that we're sending so like the email and password and this will use the schemas or the schema that we made in the last video which is user create and the last one is just our database session so orm dot session equals fastapi.pen and this will depend on our get db function that will create in a second so in services what we can do is create a function that will just retrieve a database session so if you've seen the last videos we have something very similar if not the exact same there as well and this function is just get underscore db and we need to import the database library so make sure you have that and you probably do if you already you made this create database function and what we need to do is just say db equals underscore database dot session local and then try uh yield db and then finally db dot close so we don't oh we don't leave a recession like unopen or open sorry so back in create user what we can do is just first of all in fast api depends we can call services don't get underscore db and the reason why like when i'm saving creates a new line is because i have the black formatter uh so every time i save it just reformats it but yeah so we can say database user and the first thing we want to do is check to see if a user has already been created given a certain email and we want to handle that ourselves so in here back in services we can say async def get user by email and this will take in a email which will be a string and also the database session so db underscore orm which we don't have that's what we need to import so import sql dot orm has underscore orm and then here we can just say dot session so get username by email that will basically query the database so we can say return db dot query and we can pass in the user model so here we can say import models as underscore models so there we can say underscore models dot user and then filter the under the models with the user.email and then if it's equal to the email that we've passed in let's get the first user for that and that will just return a user so if there is a model if there is a use that exists given a certain email then it will return that user otherwise it will just return none so back here we can in main.py we can say services.getuser by email and we can just pass in user.email and actually lastly the database session so db as well so what we can do now is check so we could say if db user so if the user does exist we can raise a http exception and we can say the status code is going to be a 400 and the message will be email already in use otherwise we can go ahead and create it so back in services.py we can create a function that creates our user so we can just say async create underscore user and that will take in the user underscore schemas we don't have that so just import schemas but back here we could say schemas dot user create like that and then just the database session so orm dot session and this will first do user underscore object equals models dot user we can say the email equals the user.email the hashed password is what we'll do now so of course we're sending the email and pass so when a user creates an account they send their email they send their password but the password they send won't already be encrypted we need to do that ourselves so in order to do that in the last video we installed passlet and we'll make use of that to hash so we can do import passlib.hash as underscore hash and then back down here we can call that we can say underscore hash dot bcrypt dot hash pass in the user hash password and that will just hash it automatically it uses like a very heavy encryption scheme which i think is sha256 um but yeah that's it's really really secure so we'll do that for us and then finally we can do db.add so we can add the user object to our database we can commit that then we can refresh on the user object itself and then finally just return the user object and there we go so back in main.py what we can do now is call it so we can say just return awaits and then the services dot create user that'll take any user and vb so we can go ahead and run this now hopefully it should work so if i do uv icon main call on app dash dash reload hit that back here so if you go to port 8000 and then on docs you'll see this swagger um interface so here like we can go ahead and create one so i hit try it out email is harry at say hogwarts dot com we'll set yeah string is hash password of string hit execute and email already new so i may have already done this uh before um but we can try something like ron at hogwarts.com execute already in use as well okay um you can tell i'm a harry potter fan um let's do snape execute ah okay maybe i did something wrong so in services we did get user and i think the reason why it's not working out is filter a user has a weighted away aha okay i think here we need a weight so on line 15 or where i have line 15 we have db user services get used by email i think we missed out the weight there maybe that could have been it so if i try something like i don't know um john hogwarts so yeah i executed that now it's working fine what was missing was that i wait um but now what we get back isn't ideal but it's showing us it's telling us that it's working we get the id of the user so john hogwarts.com the hash password so not string that i sent like i literally the password was literally string um but this is it in its hash form and then just the email what you'd kind of want to send back and what we'll do is send back the token so when a user user registers they'll automatically be signed in but this gives us a good indication um as to that in the fact that it's working so back in main.py we can go ahead and create a another endpoint and this endpoint will return a token so when a user logs in so type in their email and password and what they'll get back is a token and that token will allow them to authenticate themselves whenever accessing the like authenticated areas of the app so for that let's go ahead and create an endpoint call it app that will be post and we can say forward slash api token and this will be again asynchronous and we'll say generate token like so and this will take in form data so form data will be using security.oauth two password request form bit of a mouthful but you'll see what that does in a second and we'll say it depends and then the next thing is of course the database session so orm dot session equals underscore fast api dot depends and then services dot get underscore db say pass for now but what we want to do is back in services we need to go ahead and create two functions that we'll need so the first one is a function to authenticate the user so for that what we need to do is create an asynchronous function call it authenticate user that will take in an email which is of course a string and the password that the user enters and submits along with the database session so rm.session so to authenticate them first of all let's get the user itself so let's check to see if the user exists so await and then get user by email database session and then email so if not user then we can just return false and then if not user dot verify password and then the password so remember verified password is this function that we wrote in the last video in models we have this verify password and what this does is again it uses this the passlip bcrypt function verify or library decrypt and what it does is it takes the password that we submit in like the login form and the actual hash password in the database compares it to and sees if there's a match if there is it will return um like or authenticate otherwise if it's not authenticated we can return false and this of course can be written in one line but just for clarity and then lastly we can just return the user like so the next function that we want so before we jump back into main.py um we want a function that will create a token so async create underscore token this will take in the user model and you can tell like we will be you calling this will give us a user we'll pass that user into this function this create token which will then generate our like token um so we can say user underscore object schemas dot user and this really handy function called from orm and what that does it takes in a our model for example our user model and then maps it to our user schema so for example id from our model will be map to map to the user schema id email whatever you have and then we can say user just like that and this now is a user schema object and then lastly we can say token equals and we'll be making use of the library again which we installed in the last one which is pi pyjwt we can just do import j wt as underscore jwt and now here we can say the jwt and encode the user object dot dictionary as a dictionary and then we need to throw in a our jwt secret so to do that like usually you'd put this in the env file uh however just to keep it like i mean you would do that we're not like put deploying this production or anything um but in case you are planning on doing something like that then um yeah i i recommend putting this in the env file but here we can say my jwt secret doesn't matter what you put as long as it's a string and then here back in the create token we can just say the jwt secret and that's now our token what we can do is return the kind of dictionary response or the json response that we're going to have so we can say return dict and then the toke access token oops token equals token and we can also say the token underscore type butterfingers today bearer like so so that's our authenticate user function and create token function we can now jump back into main.py and make use of that so first of all we can say user equals await and then services.authenticateuser and then from form data so this thing that we have here we get we can get the email and password the email itself comes from dot username and username is just like a very generic name you know of course like sometimes it's not an email it could just be a standalone like username but i guess usernames very generic word for it but in our case this form.username will just be the email so that's what it's referring to for us and then here we can say form dot data form data dot password and lastly the database session and next we can say if not user then raise underscore fast api dot http exception say status code of 401 and the detail we can say invalid credentials you know we don't want to tell them that the email is wrong and the password is wrong just that like in general it's just wrong just to be secure and safe so lastly we can just do await create oops services dot create token and this will take in the user and that should be it so back in the interface the api interface we can just refresh and here you'll see the generate token uh endpoint we can use that and you'll also notice the application is not application forward slash forward slash json as we have here it's uh x dub dub dub dash form url encoded and we can try it out we can say username so i'll do john fogwarts and then string so put in whatever user you already created if you want to get back to token execute internal server error and the issue is in services this takes in have i ah wrong way around yeah it's so we can just say db equals db and email equals email ah okay never mind mistakes happen um but we can try that again execute and there we go so i get back this access token which we'll use to authenticate so we'll send this token every time we're making a request to an area that requires authentication such as like when we're getting our leads you know we want the leads for this user and this access token is where it will be used um and also just the token type but if you were to try a user that doesn't exist say abc hogwarts.com execute we get this invalid credentials with a 401 status code but that's it when it comes to creating a token so what we've got now is we have our create user gen and generate token endpoints the last thing is one to actually retrieve the user so we can say app.get and then we can say api forward slash users dash me and of course there's no kind of like parameters being thrown in here me could mean anyone but we're saying me as in the actual authenticated user so we can do response model and then that will be schemas dot user oops and we can do async get user this will take in the user which will be a user schema and that will be based on fast api depends that one we need a function to actually get the current user so back in services we can say i just shrink this a little bit we can create a function called get current user and that will be async get current user this will take in a token so the token that we get from when logging in and then we can say fast api and we need to import fast api so we can do import fast api as underscore fast api and this here will be fast api dot depends and what we need is the oauth 2 schema so again this is something else we need to add and in here we can also import fast api dot security as underscore security and we can do something like the o auth 2 schema equals security dot o auth 2 and then oauth to password bearer and this will have the token url and that will be api for such token like that and we can use this in the pen so we can just pass in o auth to schema like so and then the next thing we just need is just the database session so db [Music] is orm dot session and that will equal fast api pens actually we don't really need that it would just be that so we'll pass that in anyway um and this of course needs to go first oops but now in get current user we can do try and say the payload equals underscore jwt dot decode so decode the token that we uh we've uh sent back um which is the exact same one that we which would in theory be the one that we get from when logging into the um app but we'll pass it back so we'll say token and then jwt secret and then algorithms and it's using hs so that's just the encryption algorithm and then we can do user equals db.query and then the models dot user dot get and it will say payload and just the id that has come with that payload and then we can do accept uh so if any ball else fails we can do fast api dot http exception say the status code is a 401 and then the detail is invalid email or password just like that and then finally we can just return the schemas dot user from orm and then just the user that we get so now back in main.py what we can do is we can say so first of all we have the user that we're getting and we can have a dependency which is services dot get current user and this will basically just return a user very simple um so the error that we're getting is invalid argument for response field in check sql is a valid pedantic field type ah yep so actually back here in the get current user so what we need to also do is i was mistaken so we also need to with the db session we also need to set that as well so that too of course because we're not you know we're not really passing anything in so we have to actually set that uh so we can say fast api depends and this will just be the uh get underscore db just like that so the reason why we're saying it here is because we're not actually passing in a um a orm session unlike like the other examples where we are in our case we're not so we need to do that there but that should be it now that should work hopefully the terminal is still showing yeah so we're all good but now back here we can do this users me and you'll see two new things so the first one is this authorize the second uh are the lock icons so what we can do is if we go here click on the lock you can type in the username so let's say john hogwarts and then string as password authorize to the right password yeah so i just typed in the wrong password but yeah now we get this kind of if everything worked out well on your side we get uh you'll see this model you can just close it but now you'll see this lock is now locked it's no longer unlocked so what we can do is try this api users me try it out execute and we get back the email and the um id so that's the current user if i were to sign in with like another account let's actually create one let's say create user try it out say rhythmic gmail.com save this password and set a string execute so now if i first just log out and then back actually let's try it with oops so now if i go so i've logged out my old user and if i go here with that i can just type in say rhythmic by the way this isn't my actual email but string authorized and now if i were to try out api users me try it out i get back ah execute i get back rhythmic gmail.com and with the id of four so that really sums it up like we've uh gone ahead and created an endpoint for creating a user which takes in a email and password it hashes it uh and stores that hash password in the database we also have an endpoint for generating the token and if you're a bit unclear as to how these endpoints will actually work hopefully it will become a bit more clear when uh we jump into react but this token is essentially like our way into the uh like the secure secured parts of the api um so you'll create some so in this app you'll create leads uh and in order to get those leads to create leads to update leads and delete them you will need a token to do that and this is what this token will do and um with this user's me uses me we get our like um just retrieve the user that's currently that is signed in that is authenticated but actually one last thing i want to show is if we go to let's say if we generate a token now say rhythmic at gmail.com and the password is string execute so if i take this access token so if i just copy that and if you go over to jwt io and then here just paste it in you'll see here like the decoded version of it so it's telling us like it's type jwt uh and the algorithm image is hs256 and the payload is rhythmic gmail.com and id so yeah so it tells us yeah like it's um uh it gives us the information from that and uh which is quite nice um but yeah that's that's really it that's the last thing i wanted to show you in the next video we'll create the endpoints it won't be as hefty as this video is probably the longest one um but we'll look at how to create leads and create all the endpoints regarding that but other than that i hope this video gave you some understanding as to how authentication works with um fast api and uh yeah i have a discord channel so feel free to pop by there but other than that i hope to see you in the next video
Up Next

Deploy FastAPI on Ubuntu: CRUD with PostgreSQL, Gunicorn, and Caddy
@TutLinks
11.1K views•2020-12-30

IFS Therapy Demonstration: Complete Session with Unburdening
@IFSCA
95.9K views•2021-01-13

FastAPI vs Flask vs Django: Choosing the Right Python Web Framework
@TechWithTim
302.5K views•2024-05-26

Game of Thrones Opening Credits: A Cinematic Analysis
@gameofthrones
46.3M views•2011-04-18
Related Study Plans & Knowledge Roadmaps
Structured learning paths in General & Interdisciplinary Studies

![FastAPI полный курс от А до Я | Часть 1 [Junior]](https://i.ytimg.com/vi/WLch1agbg1s/maxresdefault.jpg)












![TUTORIAL - Banco de dados com PYTHON do jeito FÁCIL [Atualizado 2024]](https://i.ytimg.com/vi/7xQhlf8qnsE/maxresdefault.jpg)





























