Angular(v14) JWT Access Token Authentication & Refresh Token

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi everyone welcome to our channel so this is part one video on angular 14 jwt access token for authentication and refreshed okay so in this video series we are going to implement an angular application with jwt authentication and we also use refresh token whenever the jwt token expires to renew it okay so in general awt token is a encrypted string but it is made up of three components like header payload signature so as a ui developer you need to know all these things but it is better to have a idea how jwt token is framed okay so in general header will contain the type of algorithm and type that determines what type of token it is okay and the payload contains all the clients of the authenticated user like email username user id phone number all kind of user information can be stored in the payload okay signature signature is the type of encryption that has been used for creating the token okay so basically the string what we see as a jw token is comprised of all these three ingredients okay so let's create a sample angular 14 application and try to implement the jwt authentication okay here is the angular cli command for creating the project so cli command is like ng space new space name of your project so enter to create the project and while creating project it asks us whether to include the angular routing or not please say yes because i am going to use some lazy loading modules in this sample okay and i am going to choose the normal styling that is css project created successfully let open my project in visual studio code editor so here is our angular project okay which is 14 you can check the version in package.json file okay and now let's try to install the bootstrap package into our application so that we can consume the bootstrap component for developing a sample application go to bootstrap okay and go to the home page first and here you can see the comment for installing the latest version of the bootstrap package so let me copy the command open my terminal okay install the bootstrap so after completion of installing bootstrap we have to configure the bootstrap css and js reference files into the angular json file okay go to angularjson file so here in the styles array add the reference of the bootstrap ok same way we have to reference js file as well in the scripts array okay now let me add the bootstrap navbar as a menu item in my application so go to bootstrap website go to docs and go to the component section and go for navbar okay and let me copy this number and what i will do go to appcomponent.html where it contains the entry html default html so let's replay replace everything here okay replace now okay so container fluid you can check these styles will available in bootstrap okay on navbar brand i want to anchor tag like awt auth demo and it should be like my home navigation router link and it should display like a brand okay like a head that like a logo now bar brand plus i can apply okay now let's run the application and check so open terminal ng server and you can access our sample application at localhost 4200 and you can now see nice bootstrap menu applied to our website okay now what i want to do is this is my home page url right so i want to create one simple component angular component like home that contains a simple welcome message so my main idea is this home page is way either user is authenticated or not authenticated any kind of user can use this page like a guest page okay anyone can consume the home page that is the ideal goal so for that let me create a simple component home component okay so for creating the component ng generate component and my component name is home i don't want any spec files okay now run this cli comment okay now home component got created in app routing let me configure the home component as the home route okay so path okay that is home path component home component okay and in the home component.html let's add some welcome message something like welcome message okay i have already prepared some useful html only okay so copying that code snippet paste it here if you want pause the video and you can type enter a card now if i go to the website i got nice welcome card right so this is my home page so anyone can access this home page regarding regardless of whether the user is authenticated or non-authenticated now i want to create a login form okay so i don't want to create a login component directly because in real example along with login there are several different steps my that may include with login like registration like this process okay so what i will do i just create one module future module which i want to load lazily inside of that future module i want a component like login component okay so first let me create create a new future component or child com sorry new future module or change child module okay so ng generate module okay and auth module name okay i want routing as well for my child module okay so you can give flag like iphone iphone routing so run it okay so if i check here i can see auth module got created with the routing module file as well now in this module i want a login component okay so let me create a new component that is login inside of the future module that is auth module okay so ng generate component where i want to create instead of the auth right so path author folder name folder name module folder name and name of the component name of the component is login okay and i don't want any spec files i have created the login component as well now what i will do i will go to first i will go to app routing module i just want to enable the lazy loading module level okay so the path contains r then load children okay arrow function import auth earth module we configure our module for lazy loading now go to auth routing module here we have to configure the login component route okay so path like login and component like login component okay now in login component html we have to create a simple login form and then we have to call an api to get the authenticated authentication token which is a jwt access token as well as the refresh token but how we can get okay for that i have created a one mock api repository in my github okay so that api uh created with framework nest js which is a uh framework that builds on node.js means nothing but a node.js application okay so [Music] this is my github link and if you go to my repositories and here you can find nest if you click on it here is the documentation i have specified everything step by step let's go through them first thing is you have to clone this project because i have i have created the mock jwt sample node server application okay after installing after cloning this project you should contains the nest js framework in your application for that please make sure to run this command by opening the command prompt anywhere so this will install nest jscli globally into your local machine okay next after installing after completion of nest js installation go to this repository root folder and again open the terminal and run npm installed that going to pull all required packages required by this nest js application okay once that is done we have to start the server so command to start the server is npm run dot colon dev you need to specify same command in the terminal so that nest js application starts running so now it is available for uh using for jwt authentication okay next here is the login endpoint okay which one we have to use in our angular application and here is the payload username and password okay this property name exactly use this only because server if you change one character server can't recognize that their query parameters right their payload parameters so we cannot change these uh property characters so use exactly them and for testing use username equal to test and password is one two three four okay this this is the hard coded credentials that was using by this application okay use this one once you successful you get access token and refresh token as a response okay and if you want by default 1800 seconds to access token is actually that means 30 minutes but we are learners we want to test refresh token right we cannot wait for 30 that's sorry 30 minutes uh to learn about the refresh token right so what you can do means in this project instead of src in the auth folder instead of the auth dot module.ts5 there is a configuration like this okay jwt module registration there you can change these seconds like you give like 60 s means 60 seconds one minute so token will be expired in one minute so that you can test refresh token uh logic immediately okay so refresh token endpoint is this one here for refresh token you should send both expired access token and refresh token value as a input parameter once they are valid this endpoint going to give the new access token and new refresh token as a response okay so this is about the response token endpoint and finally we we have to use some secure endpoint right i have created something like favorite movies which is a secured endpoint means if you want to consume this endpoint you should have a jwt access token as a request header as an authorization adder to the request then only you can get a response like this something like movie name and the genre okay so that's about the uh my mock next year application okay so now we are going to next we have to implement the login and we have to consume this endpoints okay now we will create a small login form and we are going to consume our nest js application login api and we are going to resume the access token and refresh token as a response from the login api on successful authentication okay so let's add a form here simple form okay container let me add some pleasant for a heading like sign in okay and to add the email and username and password to enter the username and password i need two input fields so go to bootstrap and go for form section go to our view copy this do okay i don't want this line okay and duplicate this one okay and level only txt username as i need to id username okay type will be text is same way pxt password password okay id will be this one and it will be a password okay and let's add a button here perform submission okay like login login button okay ptn btn primary okay from click event add a method like user login okay copy this name user login and add it in logincomponent.ts for now let's empty method so first let's create a form type okay like login model so let me create a uh interface ng generate interface and this interface is specific to this login component only we don't we use anywhere else so what i window i will create inside of the auth module so specify the folder name auth and name of my model that is login hyphen model okay create so model is created so login model so properties inside of this interface will be username and password okay but copy those property name from the i have shown you right my next gs documentation so if you go to login endpoint login endpoint this is login endpoint and it requires payload like right username and password so use same property names so that form data directly sent as a payload for the http course okay and the next property password which is also a string okay now inside of the login component.ts5 let me declare a login form of type login model okay so initially username will be empty password will be empty okay and i am going to bind this login form to my html input field in the login component.html file right so here i can use ng model ng model equal to dot username okay and copy this and this will be the password so since we are using ng model right we must uh import the forms module in the auth module so go to auth module and import the forms module okay forms module now see the error showing on the login html con okay so now we are reading and storing all our uh com data to this right so in the login component we have to invoke the api call so to implement the login api call we have to create the service okay so this is login service and it's going to return some token information which required by entire application right so we should not create the service instead of the auth model or auth module it's better to create some shared folder inside of it we should create so that this service will be available at global level for entire application okay so let's create the service file ng generate service right service and i want to create a folder like shared in the app folder inside of the app folder inside of the shared folder i want one more folder like auth and name of my service i am going to name it like auth so the file gets created as auth dot service dot ts file okay and i don't want any spec files so open our service ctrl so our service so let's inject the http client instance okay that's going to load from import from at the red angular common http okay http client since we are using http client right we must import the http uh module so in our earth module let's import for not auth module in the app module level okay root level we have to import our http client module http client module import it okay now go back to our service let's create a method like user login okay and it's going to receive payload we know the payload type that is login model okay and this dot http dot post mine is a login is a http post method okay so copy the url from here and to use authentication we should run our uh nest js application right so please clone this application and follow the steps since i have already contains the nest js application in my system i am going to start the next js application for that command is this one so let me run my next gs server okay run it so next gs server is up and running now let's go to our angular application and here let's get the login okay which is http post method and it should pass the payload okay and we know from here documentation it's going to return this token refresh token right so let's create a model for this response okay so for that what i can do ng generate interface i want to create this interface instead of shared folder and instead of auth folder okay so shared earth a name of my interface that is token iphone model okay create it since it is our api response model right so token model just copy the property names from here both will be the string types okay now go to our service or service so here pipe and i will use map method from rxjx okay data nothing but the response okay where tokens equal to data just convert as our token model okay now let's save the our token data into the browser storage browser local storage because we have to access from the browser local storage throughout our application if the brow if the user closes the browsers and come back also our application can uses the tokens okay for that reason we have to maintain them as a state that state is nothing but browser locker storage so local storage this is a direct method and set item so you have to space key value like we have to store the data so i will give key like tokens and i need to save this tokens object so for that i have to stringify them so json dot json.stringify because it it will lock storage storage that is string so my tokens model is saved as a string and just let me return true that api call is successful if at all any error record let's do catch error and you can call something like your api logging api okay i'm just doing console.log and i am going to return false means api call failed so off means it's an observable it is returning expecting so i am using off that loads from the rsjs operator this off i think it gets imported you can see here okay so if api calls success we are returning to because we are you face we are returning false okay so this is my service call and here one more thing we are storing our token data into the browser session okay now we have to consume this method into our login component.ts file so to the constructor let's inject instead of the user login this dot service dot closer login and we have to pass up the payload nothing but our login form okay and i am going to subscribe for the data if the data value is true i will show simple alert message like success else alert like a login field okay so let's test and run whether we are able to successfully get token or not okay so our angular application runs at clock lost 4200 okay i haven't created a login menu navigation right let me add a login menu here okay login link for that go to appcomponent.html okay add a new view like reflex you else and the class will be now but now okay let me copy the menu styling from bootstrap [Music] that's fine let me copy this one of the link one ally okay and router link will be auth slash login okay and this will be login okay now we should see login menu um some design issue let's fix sorry this should be inside of that our dew container fluid tube okay i think now styling issue should fix okay now i got login right if i click on login see now i got login form now inspect element to check the network call okay and we know test user credentials that is username is test and password is one two three four so test and password is one two three four click on login see i got success select that means api call is login api is successful so if you click here and if you see the payload password is one two three four username is test and in the preview now here you can see access token and the refresh token right and if you go to application tab and if you go to the storage section and in the local storage under our angular application see okay store this is browser session so if i close this browser also these will be there so next time when user opens applications so applications can read these existing tokens and check whether the tokens are valid or not so we are successfully calling the login api with test credentials and we got token as a response as well next this token contains some user information payload like email and claims all those things right we have to extract those details and i can use like uh once user is successful i will hide this login button in this place i am going to show the user email address something like that email or user profile name something something user related information i can show right for that i need to extract the information from the token right next we are going to do that now to do to decode the jw token we will install a library like earth zero angularjwt okay so we we need a new library that is r0 angular jwt so this package helps us to decode the dwt access token by the way along with decoding jwt access token it also provides some wonderful features for authentication so let's check them as well so one thing is it can decode the token and another thing is directly with the help of token we know whether the token is expired or not okay and some of other features like token uh can be registered jwt module as well what is the benefit of registering module means so for a secured endpoints we have to pass our jw token as the authorization adder value right so if you configure the jwt module okay that adding of jw token to every request automatically taken care by him by it okay and it provides lot of configuration okay how to the token should be configured like which domains configure um which domains creativity token must be added and for which urls it must be excluded like that you can configure okay and hello domains disallow domains and by default my jw token is a barrier token so barrier token authentication on only to defend but if you want to use the different type of earth scheme then you can specify that okay like that there are a lot of configurations which we will understand when we explore them in our code okay first let's install this package install the auth package so after installing package let's create the instance of the jwt helper server okay like jwt helper equal to new jwt helper service okay so that loads from auth0 angularjwt library okay now using this uh instance we can decode the jwt token so now here what i will do dwt helper dot eco token to the decode token we have to pass our access token value okay so for now what i will do i will just console log the decoded data okay so now let's take it what are the properties we are going to get from the decoded token so here is my login page and we know the test credential and open the console okay now click on login it is successful right and now here you can see the object like from the d this is the decoded object so token contains email expiration and sub sub is nothing but the user id and the username okay so let me create a interface that represent this decoded token object okay so for that ng generate interface so i want this interface available throughout the application for that i am going to create inside of the shared auth folder and name of my interface i will name like user profile okay now go to user profile let's populate the properties email string exp expiration number nothing sub number okay use the name string okay now go to our auth service here what i will do i will create a behavior subject why i am going to create i will explain okay so user profile okay let's initialize with behavior subject and its type is either user profile or a nullable value initially let's pass null data okay now here instead of login to console.log where user data equal to and convert it as user profile data once encryption is done this dot user profile dot next so for a subject we have to pass data means we have to use next okay and pass the user data now we have our authenticated our decrypted user token information here right in this observable now what i want to do means i want to display log it when user is not authenticated and i want to display email id in the place of login menu item when the user is authenticated okay so before doing that first let me go to login component instead of showing alert messages okay for failure just log console okay and if the authentication is successful let's land land on home page okay for that we need a service like router service router service that loads from the angular router okay so if it is login is good then this dot router dot navigate to home page okay now let's focus on menu item displaying based on the authenticated user okay now go to appcomponent.html file so here is the our auth login data right so in app component let's try to read the user information app component.ts5 okay let me create a variable like user profile which is of type user profile or nullable okay so now in the constructor let's inject our auth service auth service okay and implements ng on init method on init method okay now instead of the ng on in it let's try to listen for the auth service user profile data okay so subscribe for data okay and assign it to our user profile equal to data okay and it should be a nullable now using this variable information let's toggle the menu items so how to do that so to display this login item i can apply and give okay like so what is the u variable user profile right so user profile okay i'm checking null values okay so that means if it is null it will return zero okay equal to equal to zero that means sub means i have mentioned that it is an authenticated user id if it is zero means user is not authenticated so in that case it will be zero in that case we are going to show the user name sorry login menu item if at all okay just duplicate this one and instead of equal to equal to zero let's say greater than zero that means user authenticated at that time there is no navigation here simply hrf equal to hash and here i want to display the email address user email address user profile dot email okay now let's test it okay if you reload i can see login login page okay enter the test credentials see i am navigated to home page and here you can see test test.com which is my email means user is successfully authenticated so this is how we can decode the jwt token using the library like auth0 dwt angular okay next we are going to consume a secured endpoint okay that is nothing but a uh here is our endpoint secured endpoint so this endpoint for to consume we need to pass the jwt access token as a authorization header value okay next we try to implement this now within my next gs application i have created one endpoint like favorite movies endpoint and response looks like this okay so to consume this favorite movies endpoint we have to pass our jwt access token as a authorization header to the api value okay so first let's create a small module like movies inside of it we will create a component like favorite movie so inside inside of that component we are going to consume this endpoint okay so let's create ng generate module and name of the module is movies i need routing as well so i can add flag like iphone iphone routing okay now i have movies module okay so let's configure the lazy load routing in the app routing module okay go to app routing module here let's configure the lazy load module okay so let me give a path like movies and load children like import movies movie module now let's create a component in inside of the movies module so the component is like five movie component okay favorite movie component ng generate component instead of movies module right so specify the folder path movies and name of the component name of the component is i have movies i don't want any test files so skip yes okay now the component is created now let's create a our api response model so this is the api response model let's create a model for it okay so ng generate interface okay movies inside of the movies folder i want so this is name of my interface response model name go to the interface let's add these properties id will be a number name will be a string joiner will be string okay now let's create a service to invoke the api call ng generate service inside of the movies folder my service name will be movie okay so file will get created like movies.service.ts5 okay and skip the test files okay if i go to my movies module movies module i have favorite movies component favorite movie.ts which is a response style and movie service file okay now let's inject the http client instance okay let's add the logic for invoking the api call get movies return this dot http so this is a get method and i am going to receive array of movie type and here we need to pass our api call okay so service is ready now let's configure our favorite movie component in movies routing module so go to movies routing module okay here patil like movies okay and component will be the file component now we have to consume the our service into our favorite movie component right so go to favorite movie component.ts5 and inject our movie service okay and now let's add a variable like five movies okay initially empty array and in the lifecycle method let's invoke the movie service okay subscribe so data so this dot file movie is equal to data okay now i need to bind this to my html so go to movie component or html5 okay so let me use some bootstrap cards for binding so go to bootstrap website so go to cards and scroll down let me copy this side by side okay and paste it here since i am going to loop let's remove the duplicate columns let's loop it and g for let 5 off so what is the variable 5 movies okay and i don't need any image tag okay and here title will be our name of the movies dot name okay here in the paragraph let's bind the turner okay now let's add a favorite movie menu item so go to app component.html go to bootstrap navbar component so from here let's copy this new tag and add it here and close the due tag okay and then next ul and like close the ul tag okay and next let's add this nav bar expand lg class okay now i want to display this movie item when the user is authenticated so i can copy this if condition add it here and this will be movies okay and i can add a router link like slash movie slash file iphone movies okay let me check routing movie routing okay now let's test once we login then we navigate to movies menu item so here is our sample click on login enter our tested ad test credentials are successfully logged in and we can see the movies menu item if i click on it now i am on movies but api call not happening so here api call 401 another that means user is not authorized okay so that means for request we have to send the api call if i click again you can see here in the networks to this request header we have to add authorization header and to that authorization we have to pass our jwt token as a value okay one way we can do is manually adding authorization header at the every request or else you can write the interceptor interceptors okay but since we are using a jwt angular library if that help with that help we can uh utilize the automatic adding of other network means we now need to write the code to add the authorization headers okay so to do that first go to auth service i have to write a method that method should return the access token as an output okay so auth service this is our service right so here let me write one method like get access token okay so where local storage always try to get from local storage or token data okay local storage dot get item and what is our key tokens right so use that one okay if local storage data exists then we have to implement some logic or else we are going to written empty string means no token is available okay if local storage token exist then where token if we will pass it okay json json.parse local storage and we convert them as token token model okay now what i will do let's check whether the existing token valid means it is expired or not so it is token expired okay to check that we know we can use the jwt helper service okay this dot jwt helper dot is token expect to this token we have to pass our access token so token dot access token okay so we if it is expired uh this value will be true okay so in that case if it is expired is token expired then what i want to do means i want to remove the data from the behavior subject that is user profile okay pc dot user profile dot next i'm going to pass null value means token expert so i am emptying the data and return the empty state means no token like back to token available okay if at all token is not expired means token is active in that case where user info equal to this dot jwt helper dot d code token just a decoding token okay token dot access token and that type will be user profile type okay now pc dot user profile observable will pass new user info decoded user info and finally return the token as the output okay access token returning as an output okay this is our private method so this method i am going to use in jwt model that loads from the at the rate or zero slash angular jwt library okay so now what we will do let's go to let's go to jw uh app module okay here let's import the jwt module awt module okay so jwt module that loads from the auth 0 angular iphone jwt library okay for root here i am going to add some configurations like jwt provider options okay so in that provide property awt option that loads from the library next use factory so i am need to pass a factory method here okay so to do that here let me create a function that function will be used as a factory method okay function jwt options factory okay and to this method we have to pass our auth service because we just created one method right that method we are used inside this okay service okay now here we need to return it object lateral just like configuration so first one will be token getter okay so this property will take say arrow function that arrow function must return the access token as output so add arrow function and we know our service we have a method to return the token that is get access token we will return it from this arrow function okay so to use it here we have created this get access token method okay so next thing configurations like we can add few more configuration so if you want to check all these configurations go to auth jwt angular okay here there will be a nice documentation how to use the factory or without using factory method everything see like this configurations you can check here it is directly using config there is no factory but we use factory method approach so that factory method approach also down here it will explain how to use so where is that factory method see we are using this factory method approach okay so here allow domain means to which domains we want to add uh this token okay so what is our domain api domain our api domain is nothing but localhost 3000 okay just copy this no need no need to copy http column if you copy uh it won't recognize so don't add http all those things only host name here we have to pass okay in the quotations and we can also specify it like other configurations like it's allowed routes to which routes no need to add that token like login all those things we no need to add our token read by default so for them i can exclude them so what are the end points i don't want for my login endpoint as well as my refresh token endpoint also i'm just excluding no need to add authorization header for these routes okay like that lot of other configurations you can check in the documentation and add here okay now let's use this jwt option factory here okay and since this method has input parameter or odd service right that should be registered in the dependencies here the depth means dependencies okay so pass here our survey okay so why we did all these configurations means now offer every request to this domain excluding these urls automatically access token will be added as a authorization header let's test it you can see how it is automatically adds let's now login again test one two three four okay now clear all network calls go to movies see now i am getting some data rendering movies favorite movies okay if i check network call now it is 200 previously 401 another 8 and if you see the request header the authorization barrier space our access token automatically added we did nothing okay so with the help of this awt module from the auth0 angularjwt automatically handles the adding of access token okay so that is one of the benefit for using this library so this library water benefit till now we have seen like decoding and checking for access token expired or not and automatic adding of authorization header value to the request you can see automatically to the request request in the request address you can see other relation value added okay otherwise if you don't do this we have to manually add for every call or we have to create a interceptor where which executes uh before going request going to the servers then we have to write our own logic for adding the authorization header okay so this is all about how to consume the secured endpoint okay uh next we are going to check how to invoke the refresh token endpoint on awt token express so we are going to implement a one interceptor for that okay jwt module cannot handle it okay directly so we have to create an interceptor and then in that insert interceptor if the token express we need to call the refresh token api now on jwt token express we have to invoke the our refresh token api right so let's let's first invoke the or implement the api call in our auth service okay go to our service okay here let's create one new method for invoking the refresh token api okay refresh token okay this is my api call just just go to our github link of nasds so you can find the url and the payload so to this payload my intention is i have to send expired access token and refresh token okay some cases they won't send expired access token they just send refresh token okay depends upon how your server api works okay so that means i should have a payload which is of type my token model okay so now return return this dot http dot so this will be a post method and it's going to return new access token refresh token so same model okay and copy the api call and the second parameter will be the payload okay this is our api call logic now to test our sample let's change the expiration token in the server project so i am going to my next js application okay and you have to go to the inside inside of the src hearth folder you have to go to the auth module.ts here you can see sign-in options and expires in 1800 seconds that means 30 minutes so what i will do i will change it to 60 seconds means 1 minute so within one minute my jwt access token expert so that i can test easily right now what i will do just top the server okay and restart it again okay server is up now go to our angular website okay try to login without test credentials okay and also open the developer tools for network calls observation we click on login now go to movies okay and now let's go to home page again now wait for one minute and click on movies menu item okay so i think one minute completed let's click on movies menu item okay no content is appearing and if you see here it is 401 unauthorized but here if you observe our login credentials are gone right so what i will do one small correction let me do inaud service in previous video we have created get access token right okay so here we are returning the access token right so here there is the line of code like we are checking for token uh best suggestion is don't add this logic like taking the expiration and emptying the profit okay because we want to use the refresh token benefit rate see once the token expired automatically all login information is gone so that logic is not ideal here so just remove that logic okay now let's uh so anyway our token will be in our network application it's a local storage session here right how do we have replaced okay so now we have to utilize the benefit of the refresh token okay obviously we must get a new access token and refresh token based on the uh refresh token that is available to us okay so now the thing is how to do that okay so we know jwt token is adding as the authorization header by the uh jwt module right we have discussed previously jwt model but invocation of refresh token it cannot handle so we have to handle it that means to handle the uh experience uh to handle the our invocation of refresh token api we must create a interceptor okay so let me create a interceptor ng generate and this interceptor is like global red so i want to create it in the store and let me create it like a class so in the shared folder in the auth folder i want to create my interceptor like token enter chapter okay i don't want any test files so let me add tip test okay now successfully interceptor is created so let me go to my interceptor earth interceptor okay currently it is a simple plane class right it should be an injectable service so decorated with injectable okay and implement http interceptor okay and it should implement a method okay we have to implement this intercept method okay so what we can do first let's try to fetch the token data from the local storage okay so constant local storage token equal to local storage dot get item and i saved with a key like token okay if you have any doubt you can check in our service service we are so tokens okay first we are trying to base the local storage token okay and let's create a variable like and check whether the local store is contained tokens or not okay so if we have tokens in our browser local storage then convert them into that string we have to pass it into our json token model type okay so local storage token as token model okay now here we have to check for the token is exped or not is okay okay means not expired okay or else let's check directly is token expired okay two means true means expired okay now we can use jwt helper right now here i can inject the jwt service directly here okay but if you recall auth service i haven't injected the jwts helper service i directly initialized that is because this earth service okay this earth service using as a dependency in the south service sorry in this jwt module so if i inject okay instead of declaring here if i inject private jwt helper equal to jwt service if i do like this in all service then it's going to throw circular reference okay since because we are injecting our service into jwt module here and the awt helper service which is inside of jwt model we are as a again injecting back to our auth service that will create circular reference that is the reason i haven't uh injected it directly injected it into the constructor okay okay but here is here there won't be any circular reference issue so that's why i can inject here if you don't want to inject also not a problem you can create a object directly like this okay but when we have opportunity to inject something okay that means object can be created very efficiently then creating manually by us okay here angler itself injects so whenever you have a chance to inject please do same way private awt helper and jwt helper service now i can use this to check this dot awt helper dot is token expect to this token expert we have to pass our access token okay so each token exped false means token is still active also not expect okay so if he is token not expand then we don't need to do nothing means token is active we should not uh change anything within the request at that time what we can do we simply uh allow the natural request flow okay we won't change anything of the request flow like this you can return okay next else health means token expired in that case what we have to do let's inject the our heart service private service or service okay here just call our refresh token endpoint refresh token okay and we know payload expired access token and refresh token i need to pass it i have the token model data so i can directly pass it as a payload right pipe and use switch map okay and switch map receives new response from our refresh token endpoint okay so here now what i will do let's cover this new token response back to our browser local storage okay so this switch map will reduce the response from the refresh token endpoint and the new data must be stored back to our local storage so key will be tokens and we have to stringify it json object json.stringify and pass our new tokens data so here we save it back to our local storage latest data now we have to update our user information to our author which shows the profile observable so that it will again refresh us the object so we have to refresh this behavioral subject here as well okay so where [Music] okay new tokens dot access token and convert it as token mode for not token model user profile model now this dot service dot and user profile observable dot next and pass our user info now after refresh token when will this end point in works for suppose if the movie api requested this interceptor get executed and this interceptor it will checks for the token if token is not expected it will proceed normally request if token expires the movies movies request will be halted okay for some time halted and refresh token new api called triggering here so once new api refresh token which is a new api call successful we will get the new access token refresh token and we again setting them back to our browser storage and updating the user profile info now again i need to resume back my movies api call actually my main main api call is movies api call which is halted person due to the expiration of token now i again have i have to resume back my movie api call so for that what we can do if if i trigger now from this here the movie api call awt module cannot automatically sorry in the app module we have jwt and we know that the jwt module automatically adds the authorization added to every request right but the request re-initiated from our author token interceptor will not add authorization editor so in that case we have to manually add the authorization header before uh it's going to hit the server so here like transform request means like new request so this request contains uh originally our movies api request so here what i can do rick dot clone okay header click dot headers dot set okay here we are manually setting t the name is nothing but authorization header although radiation header okay and token can we know jwt barrier token first it should have barrier okay and next we should have our token so here it is a dynamic string right use backticks now double quotes tactic okay now we here here we have new tokens dot our access token okay so now for movies request we are manually adding the request header this is one special case within the interceptor we must add authorization because jwt model won't intercept it any further okay now return next dot and in and pass that this newly uh created request okay transform request okay that is how we have to do or suppose if some exception occurred from the ap repress token api then we have to catch the error okay we have to catch the error and we can return row error okay directly to the request initiated okay so did i added within the i added within the switch map i think it should not be inside of the switch map it should be inside of the pipe yeah okay and it should be ended with space so here we need to do something like uh so this catcher when will occurs whenever our refresh token fails means when the user submitted some invalid refresh token or even refresh token must be expired okay at that case we should remove local storage dot remove local storage dot remove the tokens from the browser and also we must set this authorization server to null value since we have to make our application logout because refresh refresh token also invalid token and then we must navigate to home page for that let's inject the service private router router service okay so here this dot router dot navigate to home page okay so this is how our interceptor look like but here all the code not returning the data okay so here we have to do one more conditional check this flow should not execute for a few api calls like login as well as a refresh token could not go through all these token checking so for that we have to initially avoid them if request dot url dot index of okay request api url if it is login login and login api if it is a login api a checking url contains login as well as or either login or request dot url dot index of our auth token url so let's copy this string and check for it okay in these two cases i don't want to execute all this code so at the time i simply written here especially we should check refresh token if you don't do this it will go for infinite loop because refresh token always try to fetches the new access token continuously okay so this condition should be added and finally our code must execute within this logic if it crosses this logic means there is something another error at that time you can simply write an error invalid request okay now all our code returning something so let's go through the interceptor again if it is a login or refresh token we won't disturb the request flow if any other call like secured endpoints like movies first we will check for local storage and features the okay and we check whether token is expected if the token is expired means not active then also we want to stop the request flow if it is expired then we invoke the refresh token api once we got new token response we again redo our normal login flow like storing the tokens again back to browser storage and updating the user profile object and now and finally the actual request okay something like secured which is stopped for some time due to expiration of token that should be re-invoked here we we are this request contain that that object okay so we are re-invoking our api call and it will go for normal call since we are manually invoking jw2 module don't have any control over it it won't add authorization automatically okay if the logic execute in this flow database don't module don't add the authorization editor that is why we are manually adding okay we should add this interceptor into our server registering to our service provider then it gets activated so go to app module so here in the provider so provider name is http underscore interceptor okay and use class we have to pass our auth token auth token interceptor okay and multi okay now we have registered our interceptor and here small correction i haven't checking the index length okay okay now let's test again our jwt refresh token how it gets invoked okay login with test credentials okay wait for one minute so that token gets expired so you can see refresh token ap invokes then again our movies api call gets invoked i think one minute completed let's click on movies menu item we are getting data now previously we got or not one on authority if you check the network calls see instead of pirate movie calls refresh token api is invoked why it is involved because in the interceptor we are checking for the token expiration if the token expire refresh token gets invoked right here what we are doing we are in this else part in the return we are invoking the token but how again after immediate call of favorite movies how it is get invoked because actually favorite movie is the original request that is halted for some time due to expiration of token so that is altered and in meanwhile refresh token is invoked so we know if the new refresh token api we got then what we are doing in the logic we are again at the end we are we invoking the our original request nothing but here in our case favorite movie so that is success in uh new refresh token access token are available okay so that is how we how to handle whenever the token expires while consuming the secured endpoints okay next we are going to implement the routing gods why because if i try to go for login page in spite of i am uh logining means in spite of i am having a token in my browser storage till i am able to accessing the login page which is not correct one so what we will do we were going to implement the gods routing gods okay to avoid the uh only if user is already authenticated we we should restrict him accessing the login page same way if user is not authenticated we should restrict him accessing the secured pages okay next we are going to implement that so to protect the routes like login page cannot be accessed once user is logged in and vice versa when user is not logged in cannot access the secure pages like favorite movies okay so to do that we are going to implement auth guards okay okay so those are like can activate routing guards which protect the routes based on the user permissions okay so let's create a auth guard in shade folder okay ng generate class okay i don't want any test files so our guard file is created let's go over there okay it should be a injectable service decorate with at the rate injectable and it should implement can active okay which is a routing guard implementation and implement the method okay it should implement connective route okay the first thing this god earth guard should be registered on every round okay so with this earth guard there are two benefit one is restricting the routes from the user another thing is whenever user refreshes the page right so at the time the user data like user profile all the information will be lost but user authentication token and everything available in the browser storage so what we will do means we are going to fetch them okay if they are empty we are going to check local browser storage and then we are populate again if the storage contain access token we again populate our user profile so that the problem like losing of authenticated user data once the page is refreshed is fixed okay so here first let's check for user authenticated information to do that let's inject our earth service private or service okay now here i can try to fetch for user profile data okay this dot service dot user profile which is a behavior subject to get the data we can use method like get value okay so this user profile either will return null value or user profile data okay if user profile is empty okay no data maybe that is due to either two reason user is not logged in really or user login but page is reloaded at the time user profile gets emptied so in that case what we have to do means which is the data from local storage okay or tokens data where tokens since this a token string since it is string right token string and where and check whether the data is coming from browser local storage okay if that is coming then we are converted as our token model so to do that local storage dot sorry not local sorry json dot pass token string as token model okay and now let's populate again our user profile okay so we have to decrypt our token data for that let's inject jwt helper service private jwt helper jwt helper service okay so where user info jwt helper dot decode token and pass our access token token dot access token okay and this will be the user profile type now let's pass our data to this dot or service dot user profile dot next okay so user info okay so what will happen all this logic whenever user is authenticated and refresh page we again uh populating the data into our user profile object so that i can see user information like email everything like menu items all are dependent on user profile rate they also get populated and they work if the user reloaded the page also authenticated state will be maintained okay till now we have solved that problem now we have to look into restricting the user from accessing certain pages okay so to do that for every route we have to define uh like user profile rules okay so go to app module app routing module here i don't want any uh rule for the home page home component okay so but i want uh for auth routing module go to auth routing module here i can specify see this implementation purely your business you don't want to do like this hardcoded way then from your api you need to get the roles okay like access read write like that roles you need to get for that you need to invoke another kind of api okay so based on that result you have to do for this demo i simply statically maintaining the user role directly here okay so so here routes you can assign additional data okay that is like using the data property so to this data property you can give any kind of property it will take object right you can define any kind of property so this property value you can read in the route guard so i will name property like required auth okay this is my custom property so for this no need no need to have the authentication right because it is a login component so i specified like false so copy this again and go to movie routing module here favorite movie should be accessed by only authenticated users right so here paste the data property and here change required auth to true okay home page we know need because user is authenticated non authenticated should have the ability to access the home page so i didn't specified any data property over there okay so now i can i can use this uh route data value in the auth guard so go to earth guard okay now we can write conditions like if profile okay dot sub okay i will check for null checking because there might be case when user is not authenticated then sub will be empty so here what i am checking sub greater than zero means user is authenticated because sub context user login id okay if it is greater than zero okay and next what i can check means if route dot so this route value coming from this input method input property activated route snapshot okay route to dot data okay so this is going to give the control over the data property we added at our routings right it will get control over this so i can fetch for this property name so where is my author god so here i am checking because some components don't have required authority so first check whether the properties exist or not okay next check for the value of the property okay so copy this entire thing and check here i will check like false so what does that mean user is authenticated but user trying to access the profile that should not be accessed after login like login page right so at that time what i will do i simply navigate user back to home page for that we need a router service private router total service okay so this dot router dot navigate home page okay and written false so this auth god expec expect some boolean type so if it is returning false it stops further execution of the request okay for suppose if user is authenticated and trying to access the uh login page again this logic executed and it's since it is returning false it won't further allow him to access the login page okay same way else means if user is not authenticated copy the center if just we need to contradict and true okay that means user is not authenticated but trying to access a route that requires authentication at that time also we just navigate and return false okay and here we need to specify true that means everything is good user is not accessing any invalid route so simply written true here okay so that is our routing route earth got so here are god fixing two of our problems one is on page loading maintaining the user state back that is one solution it is doing okay this logic and next solution it is restricting the user based on their access for accessing the pages okay and now we have to register this auth guard at our every route okay for that go to first app module sorry app routing module here i can add can activate and array because it can accept 10 number of uh gods okay routing gods earth god okay and here for home component it is a guest but still we are resisting why we are registering here it it is not about accessing the page here we want to solve the problem when page refreshed if the user on home page and refreshed then you should get the authenticated information right for that reason i am registering auth guard okay okay same way now register in our routing module okay same way movie mod movie routing module connect okay okay and finally register this is a service right finally register in our app module okay app module and inside of the providers i can specify auth card okay and before testing here is small correction so user profile variable as in the user info again okay i forgot to do that okay now here is small correction we are checking two times so it won't cause any issue just remove this first condition because if this value directly returning true or false right at that case our checking will get conflict so just remove that condition okay so now our code is good let's try to check in our angular application so here you can see test at the test.com is available okay for suppose if now i try to access the login page i should i should navigate back to home page see i am trying to access the login page see redirect back to home page so that is because once the user is logged in he cannot access the login page again same way uh what i will do let's remove token from the storage okay and from the browser storage now refresh the page now user is not authenticated now if i try to access the favorite movies page which is can be accessed only by the authenticated users so now currently i am not authenticated user right so if i try to access now also i will get traded back to landing page let's test it see i'm ready back to landing page so that's so using gods we can protect our pages so that is the end of angularjwt authentication okay in the version 14. i hope this video has delivered some useful information to you all if you like my video please do support me by subscribing to my channel soon we are going to meet with new videos
Info
Channel: Naveen Bommidi Tech Seeker
Views: 3,450
Rating: undefined out of 5
Keywords:
Id: oqSLkbfLWQI
Channel Id: undefined
Length: 118min 3sec (7083 seconds)
Published: Wed Aug 10 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.