JWT Authentication with Access Tokens & Refresh Tokens In Node JS

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's up guys welcome to my channel as you have seen in this thumbnail in this video we're gonna build an app to authenticate user with refresh token and authorize them based on the rule you all know most important feature in every application is that notification so it needs to be more secure that is why we gonna use refresh token to authenticate users you all might be thinking what the hell is refreshed okay why should we use and how should we use well don't worry guys i'm gonna cover everything from scratch before we continue those who new to this channel i highly recommend you to subscribe and press the bell icon to get notified when new video arrives so without washing time let's get started before we jump into what is refresh token and access token first take a look at an older way of authenticating user which is called token based authentication whenever user logged in we send a access token which is valid for certain time when the token expires we have to ask user again to login which is a tedious user experience to solve that problem we gonna use refresh token so what is refresh token a refresh token is nothing but access token but it has a lifetime about one or two months and access token has expire time about 10 to 15 minutes whenever this access token expires we don't ask user to login again to get new access token instead we send refresh token to the server here we verify the token and send new access token to the client with this method user don't have to login again this makes user experience much more easier to use now we know what is refresh token why should we use refresh token well for better user experience and protect our app from cross site attacks so now we know what is refresh token and why should we use let's write some code to know how first let's open up a command prompt and here we're gonna create a folder named refresh token after creating that folder let's navigate into it and initialize this with npf with default values let's install some dependencies we need in this project which are express mongoose dot env joy bcrypt json web token and joy password complexity after installing these dependencies let's install node 1 as dev dependency dev dependency make this package only available in development mode we are not going to use node 1 for production because we will not going to make changes constantly so we have to use this package only for development after installing this package open this project in vs code ok now we are in vs code open package.json file here our main file gonna be server.js which we haven't created yet for now just write main file to be server.js then in scripts object we start our project with node1 why because it will automatically restart if you add any changes then we gonna add type to be module this line of code allow us to write es6 javascript syntax that's it guys let's save this file now and create server.js file in root directory in this file let's import express and config method from dot enu call the express module and save its instance in app variable then call config method it will allow us to access environment variables like from dot env file which we're gonna create soon then we're gonna use express.json as middleware it will allow us to get json object in request body create a port variable if port not defined in env file we're gonna use 8080 after that we're gonna listen our app on define port that's it save this file and create dot env file in root directory in this file you need to add your mongodb url i am not gonna show how to create mongodb account clusters and getting url from there it's already there in previous video watch it or search it from google it's an easy process after adding database url you need to add 10 for salt you can add different number also so salt is a random number that makes hash unpredictable we're gonna use this number while hashing user password you need to add a strong password for your access and refresh token make sure both are different what's the point of having two tokens when they both have same private key after adding details save this file and create dbconnect.js file in root directory import mongoose module in this file create a error function and name it db connect add connection param use new url parcel to be true then connect to mongodb database we need to listen to the events of mongodb while connecting on connected event we console log connected successfully on error event we console log error and message and on disconnected event we console log connection disconnected we have created functions successfully let's export this function and use it in server.js in server.js import db connect file and call this function now let's create models folder for project in root directory create models folder in that folder create user.js file import mongoose module here save schema instance in a variable let's create a user schema is gonna have username which type will be string and required to be true email type will be string required and it needs to be unique password will be string and required roles of user which type will be array of string enum means mongodb allow only these three values to be added for the rule while adding user default role will be user for everyone create collection with mongoose.model method and name it user and provide user schema after creating user model export and save this file then create user token file in models folder import mongo's module here also and save schema instance create user token schema with user id type will be object id and required token will be type string and required and i had created at type will be date default value will be while adding this document time expires in 30 days expires means this document gonna delete itself after 30 days eighty nine 89 400 seconds is equal to 24 hours so multiplied with 30 it's gonna be 30 days then create user token collection with mongoose.model method and pass user token schema after creating model export that model and create roads folder in root directory and create a dot js file in it in this file let's import router from express module then import user model from models folder then import decrypt module we're going to use this module to hash password next import join enjoy password complexity modules we're going to use this modules to validate the body of request after importing all these modules call router method and save its instance in a variable then we create a post api with endpoint forward slash signup it's gonna be a async function with tricast block in it whenever error occurred we console log that error and send a response with status code of 400 and a message let's create a function to validate the body of signup request create a joy object and inside that object let's add a details we need for this api which are user name email and password we take the body of request and validate with schema.validate method let's call this function in api and pass request.body after validating request.body save the results in a variable if error occurred we return with response status code of 400 and with error message if error not occurred while validating request.body we move on to the next step here we check the user with given email is already exist or not if exist we send a response with bad refresh 400 and send a message saying user will give an email is already exist if user does not exist with a given email we move to the next step here we create a sort for hashing password with bcrip gensort method then we're gonna hash password with decrypt hash method pass the user password and sort which we have created just earlier after hashing password now let's create a new user here i am using spread operator for password field we gonna use hash password instead of the old password save this object after creating new users successfully we send a response with status code of 201 which means we have created and send a message along with it we have created our signup route let's export our router so that we can use it in different files after exporting save this file so as you can see this validation function here and api is also here it's kind of making our code look very bad let's take this function in a different file where we write all our validation functions this makes our code look lot better and easy to make any changes so let's do that first let's create a folder name details in a root directory in that folder create validation schema.js file copy this function and go to this file and paste it here we don't need these imports here so copy this and paste it here okay now let's export this function to use any different places and after exporting this save this file let's go to the arch.js file here we're going to import that function now let's save this file we have created signup route successfully now let's create a login route first we gonna write a validation function to our route so let's go to validation schema.js file here create a function name login body validation in order to login user we need email and password of user so add them in a schema validation object then we return results after validating body we have created function let's export this and save file in add.js file create a post request and add tricash block limit if error occurred we console log and send a response with 500 status code along with the message to verify the body of request import login body validation function we created earlier and use it here call that function and pass request.body if error occurred send a response with 400 status code along with the error message if it's a valid body we move on to the next step here the check user with the given email is exist or not if does not exist we send a bad request with message saying invalid email or password if exist then it's a valid email let's move on to the next step here we compare hash password and password came from the request.poly with the decrypt if it's invalid password same response we sent to the email we're going to send if it's a valid password and email then he is a genuine user now he need refresh token and access token we are not gonna write that logic here it makes our code look ugly so let's create a file in utils folder named generate tokens in this file import json web token as jwt and user token model from models folder create general tokens async function and add try catch block in it for our json web token i'm adding id and role in payload you can add more fields if you want or you could just add user id it's up to you let's create access token with jwt dot sign method you need to pass payload access token private key and you need to specify when do you want this token to expire it is the access token i want this access token to have short period of time so i'm adding 14 minutes now let's create a refresh token just like access token but change expired time to 30 days after creating both refresh token and access token we call a query to find user token with given user id if user token exists with the given user id then we delete the document from database then we create new user token with user id and refresh token after saving this document in database we return both refresh token and access token if error occurred we return error we have created generate token function successfully let's export this and save this file let's import generate token function in app.js file we call this function and pass user as param after getting access token and refresh token we send a response with status code of 200 along with the access token refresh token and message we have created our login route successfully let's save this file now now we have created both login and signup routes let's use them and test whether they are working or not in server.js let's import at routes from js file and use them with app.use method in order to test apis i am using thunderclient extension from vs code you can also use postman so after installing thunderclient or postman or any other application to test apis open the tab here i am using thunderclient if any of you using extension click on thunder icon to open app click on new request and add api endpoint for saving time i have already added signup and login apis i have just added api url set it to add post request and body details with empty strings and named it to sign up let's create user with username user email will be usered gmail.com and password to be user with you uppercase click on the send button to call api oops we got a bad request password should be 8 characters long our joi validation is working fine joy password validation require 8 characters length password one numeric value one symbol uppercase letter and lowercase letter you need to add that to fulfill the joy validation so i'm adding password like this and click on the send okay we have successfully created user our signup route is working fine let's test login route i am copying both email and password from here in login body paste both email and password let's send intentionally wrong email yep we are getting an error invalid email or password let's add a valid email and password and send request again how we got an access token and refresh token login route is working fine let's close these tabs we successfully created login and signup routes and they are working fine what about using refresh token to get access token now let's create a routes to get access token by using refresh token and logging out user let's create a file named refreshtoken.js in routes folder as i said earlier we need to verify refresh tokens sent by the user is valid or not if it's valid then only we send access token we can write verifying refresh token logic in a different file so let's create a file in utils folder name it verify refreshtoken.js file in this file import user token model from modules folder then import json web token as jwt let's create a function name verify refresh token which has param refresh token first let's save a refresh token private key in a variable now return new promise in that promise find user token with given refresh token if we couldn't find any document return error invalid refresh token if we found move on to the next step here verify the token with jwt dot verify method if error occurred return same error invalid refresh token if not then return jwt payload verify refresh token is done let's export this function and save this file go to refresh token file in this file import router from express user token model from models folder import json web token and verify refresh token function from utils folder after importing all these modules call router method and save its instance in a variable create a post api now let's create a function for refresh token body validation in a validation schema file here create a function name refresh token body validation in body of this request we only need refresh token after creating this function export and save this file let's go to refresh token route here import validation function now let's use it in api call this function and pass request.body if error occurred we return bad request with message just like before after that use verify refresh token function to validate refresh token if it's valid token then copy this payload and create new access token by using jwd dot sign method in a response send access token if error occurred cache the trader and send bad request in a response getting access token api is done let's implement logout route create a delete api and add tricash block in it if error occurred we console log that error and send a response internal server error occurred for this api also we gonna have same refresh token in a body so we're going to use same validation function if error occurred we're going to send a bad request if not then find a user token with a given refresh token even though token does not exist we send log dots successfully in a response if we found user token with a given refresh token then we gonna delete that token from database then send a same response logged out successfully both refresh token and logout apis are done let's export router to use this apis and test in server.js import refresh token routes and use them with endpoint refresh token save this file now and test them in a thunder client for time sake i have already added api endpoints and body details with empty values first let's test refresh token api let's copy refresh token from login route and paste it in a body of this request i am sending invalid refresh token intentionally now let's see what happens okay we got an error as expected now send a valid reference token okay we got a new access token this api is working fine now let's test log out to api copy this refresh token and send this in a body of this request okay we got a response logged out successfully if we log dot means this refresh token is not valid anymore let's call again refresh token api to get access to okay awesome we got an error as expected or both apis are working fine now let's close these tabs congratulations guys we have implemented refresh and access token based authentication successfully now for the bonus part lot of you guys ask me how to protect routes i mean routes which only authenticate users can access and role-based authorization so i'm gonna show you how to do that here create a middleware folder in root directory in that folder create.js file in this file import json web token then create function name at it has a parent's request response and next save token in a variable came from request.header if token does not exist send 403 status code means not authorized along with the message if token provided move on to the next step add try catch block if error occurred send same error response 403 not authorized in try block verify the token with jwt dot verify method save payload details in a variable and assign to request.user so that we can use it in a route then call next function so that it can move on to the next function we have created earth middleware successfully let's export it and save this file in middleware folder create rolecheck.js file with this middleware we gonna allow only certain users to access these routes if you want any middleware to pass parameters then create a function and add params you want to add then return function i will show you in code how create a function named rolecheck it takes params roles inside that function return function like this for every user we set default role to be user so we don't want to pass user every time we use this function so that is why i am pushing user in roles array then check whether the user have roles we wanted if role does not exist we return 403 status code if role exists we call next function that's it export this function and save this file to show how to use middlewares i am creating usage.js file in routes folder in this file import router from express import art middleware and roll check middle build call router method and create simple gate api if we add earth like this and call rolecheck function i want this route to access only by admin users for simplicity i am just written json with message user authenticated after that export router and save this file in server.js import user routes and use them at users endpoint let's test this apis now in get users details api i am going to remove x-axis token header for now and call this api as expected we got an error [Music] let's add access token and send this api again before that let's call login api to get new access token we got our new access token copy it and in user data's api in header tab add x access token property and access token has value let's send invalid token f we got an error as expected now add valid token and call this api again now we got a different error because this user is not a admin let's change this api to access all authenticated users make the changes and save this file let's call this api again we got a response user authenticated wow that's it for today guys we'll be back again with awesome video i hope you have learned something new today see you again bye [Music] you
Info
Channel: CyberWolves
Views: 8,238
Rating: undefined out of 5
Keywords: refresh token, jwt, refresh tokens, jwt token in nodejs, What are refresh tokens, How to use refresh token, How to blacklist refresh tokens, jwt auth express, jwt auth node js express, jwt authentication node js, json web token node js, jwt node js, json web token authentication node js, user authentication, mern stack, mern stack project, mern tutorial, crud mern, Authentication, authentication and authorization, access token, node js, javascript, json web token
Id: KqcEVUI7-s0
Channel Id: undefined
Length: 26min 15sec (1575 seconds)
Published: Mon Apr 18 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.