JWT Logout: The Trick You Missed in Spring Security (Solved!)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
log out from screen boot application that uses JWT based authentication is different and tricky than the log out from traditional session based authentication system and that's what we are going to learn in this tutorial hi I am ifar Hussein your instructor for this video here what we are going to learn we will learn some Basics on how session based authentication work and also learn how JWT authentication work and why we need to take different approach to log out for this and we will learn what concept we can take from session based authentication to implement our JWT log out I will try to break the whole thing into smaller digestable part so that you can understand it I hope it will be helpful for you but before proceeding to the tutorial I highly recommend to watch my previous tutorial where I have shown how to authenticate using JWT in Spring application if you have already watched it let's start let me give you a summary of how session based authentication Works in a typical application Suppose there is a browser from where your user will send the request and this is our server make it bigger place it a suitable Place let's make it simple this is our browser and Mark it this is our server suppose any user sending a login request to the server when server receives a login request it it authenticate the user then it create a session for the user and store the session in the session storage I'll draw this shortly and it response the user a reference to the session so here is our session storage let's add a database our session storage is this stores the session and now here is our response response with session reference so after receiving the response with session reference the browser stores the session reference in this cookie so when doing further request to the server it includes this session reference to its cookie and send the request so after receiving the request server look up for the session from the session storage if it find the session it does the necessary steps and response to the browser this is how this session works for the simplest form now let's take a look on how this authentication Works in rest API add a front end client make it a little bit bigger this is our client this may be our device or browser or any other piece of software that communicate with the rest API here is our server from from client it sends a login request to the server after receiving the login request the server validate the user then generate the token sign the token with the secret key and return a response to the client with the token in the body so let's draw this response send response with token so for any subsequent request where the client want to access the protected resource it request with the token in the header so after receiving that request let's add an Circle here after receiving the request it does a token validation so what it actually does first of all it check if the token is expired then it validate the signature and also check if the token is belongs to the user and if everything is okay then it uh provide the data from this protected resources but there is a feature of rest API is that the rest API is stateless meaning the request doesn't have any idea about the previous request even the token is not stored in the server so when it comes to log out of this token based authentication system like rest API it's little bit tricky because of the stateless nature of the rest API even Spring Security does not have any default logout feature implementation for such kind of system JWT toen is not meant to invalidate once it is created it is valid until it expires remember we have added expiry in our token in that I have shown you in my previous tutorial so for implementing log out we will use the session based authentication systems concept we will introduce a cash storage to store tokens like session storage we will add a flag to determine if the user using the token is logged out when a user tries to log out we will mark that token logged out and update it in the storage whenever the server get a request it lookups its cash for the token if it finds the token is logged out then it will return with response code 401 unauthorized we will use our existing database for token storage but cash storage like redish or mcast can be used in this purpose which one you use really depends on your requirement before we jump into the coding let's break the whole project into smaller tasks this will make it clearer and easier to work on first of all we need to store the token in the database so we will need a token table hence a token entity suppose this is our token table this will have an ID token to store the token value is logged out this is a Boolean type of field we will use it to flag the token if the user has logged out or not we'll also need to know to which user this token is belongs to we can map this with the user table with the user ID so we need the user ID field suppose this is our user table this user may have multiple token which we can identify using this user ID then we will need a token repository for the interaction with the database in this repository we will need two methods for database query one is for getting all the tokens created by user and another find the token by its token value now next part is to add validation rule in the service class to check if the user has logged out let's bring this whole thing in a block this is for token storage and validation next is our log out process when the user tries to log out we will search for the token from the token table using its token value then we will Mark the token as logged out and update the token in the database and we'll also do some necessary configuration in the security config file that's all we are going to do so now it's time to jump to the cing we will continue building on the concept covered in our previous tutorial if you have not watched it yet you can find the link in the description below Additionally the full source code for this project is available on my GitHub repository Linked In the description as I have shown you we'll need a token entity inside the model package create a new Java class token make it entity give it a table name token this token will have some properties we need a ID this is primary key of our token table for this we need to add ID annotation the value of this ID will rely on mysql's auto increment feature for that we need to specify the generation type using generate value and generation strategy is identity next give this field a column name of ID next we will need token for storing token value give this a column name then we need to identify if the user that using this token is logged out give it a column name is logged out then we need the relation of the token with the user it will be many to one relationship we will identify it using user ID so join column name is user ID now generate seter and geter for all of these fields now let's add mapping with the token in user head to the user class whenever a token is generated we will store the token in the database so a single user will have multiple tokens so we need list of tokens it will have one to many relationship it will be mapped by user this name is the same as the field name we have provided for user in our token table we'll also need to generate Gator and Sater for this field it's time to create repository for token inside repository package create a new Java class make sure interface is selected add name token repository it extends DP repository for token and primary key is integer as I have mentioned previously it will have two custom methods one is find all token by user it accepts user ID we will also need custom query for this select T that is for token from token table we need to join with user on tokens user ID equals users ID ID where tokens user ID is equal to the user ID that we are passing to this method and it's not logged out that is log out equals false another method is find by token it accepts token our repository is complete now we need to save generated token open authentication Service we are generating the token in register and authenticate method here in the register method we are generating the token after this we need to save this for that we need to inject token repository create a final field for token repository we need to add this in the Constructor let's remove existing Constructor and generate a new one I'm moving this to new line so that you can read it better scroll down here we are going to save the token create a new instance of token we need to name it token one because token is already taken let's rename this variable right click refactor rename rename code occurrences rename it to JWT then say token value need to set logged out the user is just authenticated so the the loged out is false and set the user here is our user created set this to our tokens user finally save it we need to do the same in our authenticate method I'm going to move this line of code into a new method so that I don't have to write the same code again and again intellig idea have a nice feature that you can extract the line of codes into a new method just a few click select the lines right click refactor extract methods give method a name save user token now in authenticate method after the token is generated here call our save user token method pass this token and user let's move this method at the end of this class now let's start the project check our database here is our new token table is created let's check this this it has the Deary fields we have provided in our token entity now let's try to register a new user open the postman here I already have the necessary information for new user registration just send a request our user is created and a token is generated let's check it in the database refresh the data here is our generated tokens value and this token is mapped with user of id1 let's check this user here this is our newly registered user now let's try to authenticate the newly created user update username send request user is authenticated successfully so a new token is generated refresh the database here new token for the user is added Let's uh send another authentication request refresh the data another token is generated and saved in our database now let's copy the first token and try to access a secured endpoint in demo request paste the token value and send request so we can access this from here again do the same with the second token copy this token set the token value in Postman and send request it's also valid token so so we can access this protected resource so at a time all three token tokens are valid but it should not be case there should be only one valid token per user at a given time so let's modify this things so that other previously generated token becomes invalid here is a plan for how we can do this first of all we need to get all the tokens generated by the user from the database then Loop through all the tokens and say it logged out to true and finally save all the the tokens in the database here is the authentication manager inside authenticate method just before the token is saved I'm going to query the database we will get the list of tokens valid tokens list by user we need to query the database using token repository we need to call find all token by user pass our user ID then we need to check if the token list is not empty if not then Loop through the token I'm using for each Loop and Lambda expression to Loop through the token list and setting logged out to True after the end of the loop we need to save all the tokens using the token repository save all method pass our token list that's it let's extract these lines of code into a new method so that we can use it without repeating the same code if we need to naming it revoke all tokens by user start the server open the postman register a new user check the database a new token is added now copy this token head to the demo URL paste the newly created token and send the request successful response let's try to authenticate the user head to the login request tab send a request the user is authenticated and a new token is generated check the database refresh the data our first token is set to logged out now head to the demo URL tab in the postman here is the token field I have the old token with this token I would like to send the request and see the response send request we are getting success response but we have invalided the token so why we can access this protected resource with that invalid token that is because though we have marked the token logged out and save the data to database we still did not instruct the spring board to block that token for further access let's do it open JWT authentication filter here we are checking if the token is valid this method is from JWT service let's open that class here is valid method here we are checking if the token is belongs to that user and if expired we need to add additional checking if the user is logged out after this username field add a new Boolean variable is valid token we need to query the database for this we need to inject our our token repository add final token repository field we need to add this field in the Constructor now it's the time to set the value of the is valid token variable using token repository find by token pass token here use map method to check if the token is not logged out or else return false and finally in return statement add logical and checking with our valid token variable we are done start the server register a new user registration was successful copy the token using that token try to access protected demo URL it is successful response now head to the login tab login the user new token is generated from demo URL with the old token try to access the resource send request this time the response is 401 now try to access with the newly created token it is successful so we have successfully implemented the first step of the project that is user will not able to access the protected resource with blacklisted token it's time to add log out functionality open the security config here in the security filter chain method we need to add log out inside Lambda expression log out URL set to log out need to add logout Handler pass logout Handler I will create a custom logout Handler later after successful logout we need to clear the security context we can do this using log out success Handler inside Lambda expression it have three parameters request response and authentication we will clear the the security context holder clear context now create our custom logout Handler inside config package create a new class custom logout Handler it implements a logout Handler interface it requires to implement log out method move this parameter to a new line we need to write here some code this code is similar to what we have written in JWT authentication filter class copy these codes from that class we need to copy from the line where we are extracting the O header up to extracting the token paste it in the custom logout handlers log out method here we do not need this filter chain remove it here is the token is extracted from the header here is what we're going to do first get the store token from the database then Mark the token as logged out and save it to the database let's scroll scroll up add a new token repository field generate a Constructor with that repository now get the save token using token repositories find by token method pass token if the token is not found then return null need to check if the token is not null if not null then sa the store token log out to True save the token head to security config create a new private final field for custom logout Handler I need to add this to our Constructor so let's remove the old one gener generate a new Constructor with all the field moving in the new line here showing an error for the logout Handler open the custom logout hand we need to annotate this class as component with this the error is solved start the server open Postman register a new user using the newly generated token let's try to access the protected resource open the demo tab paste the token and send a request the response is successful now let's try to log out open the new tab gate request URL is Local Host 8080 SL logout in the authorization tab brr token paste the token send request the response code is 200 that means the log out was successful check the database our token table the token is marked as logged out try to access the demo URL with that invalid token send request the response code is 401 we have successfully implemented the log out functionality and with that we are end of this tutorial I tried my best to break the whole thing into small steps so that you can understand it hopefully it will help I'll be back with another tutorial soon happy coding
Info
Channel: Learn With Ifte
Views: 4,601
Rating: undefined out of 5
Keywords: jwt, jwt authentication spring boot, jwt logout, jwt spring boot, spring boot, spring boot 3, spring boot jwt, spring boot security, spring boot tutorial, spring framework, spring security, spring security 6, spring security 6 tutorial, spring security authentication, spring security jwt, spring security jwt authentication, spring security jwt mysql, spring security jwt role-based authorization tutorial, spring security jwt token, spring security tutorial
Id: OpSU0VgfkL4
Channel Id: undefined
Length: 23min 10sec (1390 seconds)
Published: Sun Feb 25 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.