How to Logout from Spring Security - JWT
Buy me a coffee: ko-fi.com/boualiali #spring #learning #springboot #springtutorial #springsecurity #developpement #java #arraylist #linkedlist #springdatajpa #querybuilder #aliboucoding #alibou #validation #mongodb #springboot_3 #oauth2 #security
🤔 When using Spring Security with JWT token, there is no implicit implementation for logout. It's up to the developer to implement the logout functionality, which involves invalidating the JWT token and clearing the authentication information from the Spring Security context.
💡 One recommended way to implement the logout functionality is to use a custom logout handler that invalidates the JWT token and clears the authentication information. This custom logout handler can then be registered with the LogoutConfigurer in your Spring Security configuration, along with any other handlers you want to execute as part of the logout process.
👨💻 It's important to ensure that the custom logout handler is executed after the JWT filter in the filter chain. This can be achieved by chaining the logout handlers in the desired order using the addLogoutHandler and logoutSuccessHandler methods of the LogoutConfigurer.
👉 In summary, while Spring Security does not provide an implicit implementation for logout when using JWT tokens, it is possible to implement a custom logout handler that invalidates the token and clears the authentication information, and register it with the LogoutConfigurer in the Spring Security configuration.
🚀 With a custom logout handler, you can take control of the logout process in your Spring Security application and ensure that the JWT token is properly invalidated and the user's authentication information is cleared. So if you're using JWT tokens with Spring Security, consider implementing a custom logout handler for a smoother user experience!
Don't Forget to
===========================================
💯 Source code: github.com/ali-bouali/spring-...
💯 Free courses here: aliboucoding.com
💯 Subscribe to the youtube channel
💯 Join our Discord Community - / discord
💯 Join our Facebook Group - / 589612651142975
💯 Join our Instagram: / alibou_coding
Table of content
00:00 Intro
01:56 Does Spring provide logout mechanism?
03:56 Logout mechanism idea
06:49 Extending the class diagram
08:39 Create the Token entity
13:25 Create the Token repository
17:23 Save the generated token
21:42 Testing the changes
24:53 Revoke all user tokens
27:49 Test the changes
29:03 Update the JwtAuthentication Filter
35:24 Test the changes
37:17 Let's implement the logout
38:07 Add the security configuration
41:57 Create the Logout handler service
43:44 implement the logout handler service
47:04 Test the logout mechanism
49:28 Outro
Пікірлер: 289
COUPON Code: *EARLYBIRD20* => Spring Data J PA course: aliboucoding.com/p/the-full-guide-to-master-spring-boot-data-jpa
Thank you so much for this and your other Spring Security videos! You break down overwhelming concepts into clear smaller pieces so easily. I learned so much from just going through a couple of your videos. Looking forward to watching more!
@BoualiAli
Жыл бұрын
Glad you like them! This motivates me
Excellent videos and playlist! 👍👍👍👍
Thank you so much for this and your other Spring Security videos! Your work is truly wonderful; please keep it up!
@BoualiAli
11 ай бұрын
Thank you! Will do!
Just finished watching the previous video implementing JWT, and adding this on top of that I've learnt a lot. Super thanks man 🔥.
@BoualiAli
Жыл бұрын
Happy to know that. Happy you liked it
These are amazing! Refresh tokens would be very useful !
@BoualiAli
Жыл бұрын
Thanks. I will create a video about that fir sure
Great teacher with clear voice and content, making the life easier for the spring boot developers, great contribution and highly appreciated. Thank you so much 🥰
A lot of videos out there which rarely explain about logout! thanks a lot for this amazing video 🙏
@BoualiAli
Жыл бұрын
Happy you loved it 😊
This is the best video about Spring Security and JWT. Thanks a lot for this lesson, it helped me incredibly :)
Thank you so much, very well explained!
You are so wonderful! you teaching is very easy to understand. I watched your video 4 about spring security and i added more to watch them later!
@BoualiAli
11 ай бұрын
Really happy you liked it
Thank you so much for these updated videos. You have no idea how frustrated I got due to the out dated ones when working with Spring boot 3. you're helping me in both my full time job and in my freelance projects especially when it came to security of APIs. Bundle of Thanks
@BoualiAli
2 ай бұрын
Glad I could help!
You are the best! Thanks a lot! Mentions every side of the JWT. Basics, logout, refresh token, password change etc...
@BoualiAli
7 ай бұрын
Happy you liked it!
Amazing, Thank you and please keep uploading videos like this cause we really learn a lot from you .
@BoualiAli
Жыл бұрын
Thanks 🙏 I will absolutely continue uploading. You’re my source of motivation
Thanks, your video goes at a very good pace with clear explanations. Apart from a couple of deprecated codes, it was great. Thanks for your help!
@BoualiAli
3 ай бұрын
deprecations are inevitable. I always release new videos for the updates. check the playlists or search in the channel
Thank you again, it's very clear !
@BoualiAli
Жыл бұрын
My pleasure ❤️
Hi from Morocco, ur spring security tutorial are perfect, thank you for ur help.
@BoualiAli
11 ай бұрын
Glad you like them!
Such amazing and useful content and a better way to explain it in an easy way. We love your work and efforts. Thank you for such amazing content like this ❤.
@BoualiAli
Жыл бұрын
Happy you liked it
Well done, keep up the amazing work!
@BoualiAli
Жыл бұрын
Thanks, will do!
These videos are amazing thanks a lot. I searched many videos about jwt security in java spring boot but they wasn't easy to understand but I can learn easily and clearly with your videos thanks. access and refresh token would be great
@BoualiAli
Жыл бұрын
Thank you for the good feedback. I will make a video about refresh token
tbarkallah 3la weld bledi thank you so much Ali you're a lifesaver
@BoualiAli
Жыл бұрын
Thank youu 🙏 My pleasure
Thank you. Good job!
@BoualiAli
3 ай бұрын
Glad it was helpful!
really useful videos, keep going! I appreciate your course videos
@BoualiAli
Жыл бұрын
I’m really happy that you like my content. This motivates me to create more
Thanks a lot Bouali. It was very beneficial as always. I really admire your high quality work and please continue creating more content.
@BoualiAli
Жыл бұрын
Happy you liked it
@arohawrami8132
Жыл бұрын
@@BoualiAli Thank you Ali
He is the best Teacher on spring security. i will recommend you anytime and anywhere
@BoualiAli
Жыл бұрын
Thank you 🙏. Really appreciate that
Applause to your effort. Need to say this video is really informative and helped me extremely for implementing logout with jwt tokens. It would be really helpful if you could start a youtube series on implementing the microservices with all the features provided by spring cloud.
@BoualiAli
Жыл бұрын
I already started preparing for such course. Preparation take really long time
Thankyou Sir for sharing your knowledge.
@BoualiAli
Жыл бұрын
My pleasure
Thanks for this video Ali !
@BoualiAli
7 ай бұрын
My pleasure
Amazing, Thank you
Mashallah, thank you my brother for the clear step-by-step tutorial. Keep it up!
@BoualiAli
10 ай бұрын
My pleasure!
Awesome tutorial man! 48:20 was spot on, you got me right there.
@BoualiAli
9 ай бұрын
Awesome, thank you!
Very useful and clear explanation. Thanks Ali
@BoualiAli
Жыл бұрын
Glad it was helpful!
Thaks for your job. These guides save a lot of time for beginners
@BoualiAli
Жыл бұрын
Happy you liked it
the best one teaching spring 🔥🔥
@BoualiAli
10 ай бұрын
Wow, thanks!
Perfection !!!! 👍
@BoualiAli
3 ай бұрын
Glad you like it!
excellent Ali, I don't miss any video I learn a lot from you 😎
@BoualiAli
Жыл бұрын
Happy to know that. This motivates me
It really cool and superb content.
@BoualiAli
Жыл бұрын
Happy you liked it!
wonderfull !!! what a enrgy sir. Appriciated....
@BoualiAli
6 ай бұрын
So nice of you
great tutorial, and code works fine
@BoualiAli
Жыл бұрын
Happy to know that
Thank you so much loved the video. I was stuck and looking for a resource. It helped me alot. Love from India
@BoualiAli
Жыл бұрын
Happy to have you here. Happy you like my content
Nice one :)
Amazing please keep going this topic of security is very rare, specially with this updates of spring security 6
@BoualiAli
Жыл бұрын
Thank you, I will
@ismailforeveryone6889
Жыл бұрын
@@BoualiAli Thank you so much Mr
Thax Sir Realy Helped
@BoualiAli
Жыл бұрын
Happy you liked it
Thank you so much!
@BoualiAli
Жыл бұрын
You’re welcome
Hello from Russia, man. Thanks for your very helpful videos.
@BoualiAli
Жыл бұрын
Greetings from Tunisia 🇹🇳 Happy you like my content
Thanks for his sweet video
@BoualiAli
Жыл бұрын
Happy you liked it
you have saved the IT Industry, Sir!!
@BoualiAli
2 ай бұрын
Glad you liked it!
thank you!!
@BoualiAli
2 ай бұрын
welcome
thank you so much
@BoualiAli
Жыл бұрын
You're welcome!
Wow broooo u r amazing. This tutorial helped me to solve my problem in my project))
@BoualiAli
Жыл бұрын
Happy to know that bro.
great
thanks a lot !
@BoualiAli
9 ай бұрын
You're welcome!
Good Job !
@BoualiAli
Жыл бұрын
Thank bro
Thank you
@BoualiAli
10 ай бұрын
You're welcome
Топ контент. Дякую
@BoualiAli
Жыл бұрын
my pleasure!
Good Job Thanks
@BoualiAli
Жыл бұрын
My pleasure
Thanks and Keep It Up Bro
@BoualiAli
Жыл бұрын
Thank you. I will
¡Gracias!
@BoualiAli
3 ай бұрын
Thank you so much for the support. This is so generous from you.
good job, keep going ali 🤩🤩
@BoualiAli
Жыл бұрын
Thank you 🙏
If someone has a problem with LazyInitializationException occuring, in my case it was because i had @Data annotation in both User and Token Entities, that annotation contains @ToString which caused an infinite loop, I just replaced it with @Getter and @Setter.
@BoualiAli
11 ай бұрын
Really thank you for sharing. Keep this great mindset
@anirudh514
5 ай бұрын
You saved several hours of time for me. Thank you very much for this suggestion which is hard to notice!!!
nice content.thank you
@BoualiAli
Жыл бұрын
Glad you liked it!
@ramakrishnamogilipuri1647
Жыл бұрын
Can you also make videos for Authorization using database roles instead of enum
@BoualiAli
Жыл бұрын
@@ramakrishnamogilipuri1647 will do that
so much thankful to you sir giving this videos very useful for me. Sir pls do video on forgot reset password
@BoualiAli
7 ай бұрын
Already done. Subscribe and enable the notifications and you won't miss any of my new videos
Thank you brother, this is inspiring and realy helped me a lot thank you. Can you pls help create a lecture for messaging queues like kafka or rabbitMQ? Stay blessed
@BoualiAli
Жыл бұрын
Thank you for the feedback. MQ is coming soon
thanks👋
@BoualiAli
Жыл бұрын
My pleasure
Excellent, a video on refresh token would help
@BoualiAli
Жыл бұрын
Thanks, I will create one
it was really a great tutorial. Thanks for sharing your knowledge with us
❤❤❤
@BoualiAli
Жыл бұрын
Thanks
Thanks Bouali ! this Security vids have been a great help ❤. You are awsome!!! Just wondering if you're going to do a change password vid to? forgotten password and e mail verification ?
@BoualiAli
Жыл бұрын
Yes I will
Helpful and useful video , but it could be in easier way, you could create a new method called logout , then decode jwt , then change it date and it is all . Your explaining is very clear . Thank you
@BoualiAli
Жыл бұрын
Thanks for the comment. Just one question regarding you way of doing it. How would you for the user to update the token? (Token is stored on client side)
i think that in the LogoutService before clearing the SecurityContextHolder, in addition to checking for the existence of the token in our database, we should also check that it's not been revoked or expired.
Thank you so much AliBou !! This is very helpful. can you make video of logout from Keycloak auth server generating jwt token ?
@BoualiAli
3 ай бұрын
Yes, soon
Great tutorial! Will you create video about refresh token?
@BoualiAli
Жыл бұрын
Happy you like it. I will soon
I watched also the prev video about JWT. This videos are very straightforward and to the point. Just a little bit remark: why do you use var declaration instead of naming the proper type?
@BoualiAli
Жыл бұрын
It is just shorter to write 😅
Hello Bouali! Great tutorial as always, thank you! Quick question: doesn't revoking the user's token on every authentication forbids them to log in to the application in different devices at the same time?
@BoualiAli
7 ай бұрын
Yes, true
Excellence video. Would you create a video using Angular to logout?
@BoualiAli
10 ай бұрын
Great suggestion!
Thank you for your tutorial, I have a question that if every time the user authenticates and logs out, the token will be set revoked to false and expired is also false, but if that is the case, the database will contain corrupted fields. It's redundant and makes the database bigger when having to store the data. Can I clean up that extra data?
1) What is the use of revoking and expiring all tokens during JWT creation ( you have already done it in LogoutService class) Why doing twice ? 2)In this application user can not simultaneously login from two device ? (As soon as he login on another device, you are simply revoking all its previous tokens). Is above questions are valid or am I missing anything ? btw lecture is very helpful. Thank you.
Very cool explained everything thank you!!! One question. Isn't it more logical to just delete tokens so as not to store a bunch of invalid tokens in the database?
@medAmineRg
5 ай бұрын
i guess you can do it. it just a matter of history
before watch this video ,after doing the login process and using in my react project and user registre and login ,i save the token in storage to use for others api ,this is good or no ? and when he choose to logout i distroy the token storage.clean()
Hello Bouali, Incredible explanation and as always very useful content. So, I have a question: this implementation is solving the Multiple concurrent sessions problem, isn´t it? because I had an ethical hack just a couple of weeks ago and that was one of the problems to solve.
@BoualiAli
Жыл бұрын
Really happy you liked it Yes it should
Thanks for your effort in jwt. But i want to ask you a simple question Should we delete the previous tokens for specific user so we don't have alot of rows that we don't need in the database or not? Thanks in advance.
@BoualiAli
Жыл бұрын
This also can be an option if you don’t need the already revoked token
@mmge3967
Жыл бұрын
@@BoualiAli ok thanks
Thanks for the informative video, the only thing I did not understand is why we do the same checks in LogoutHandler as in the filter, because if there is no Authorization header or it does not start with Bearer, then the filter will not skip this request, and if the filter missed us in EndPoint /logout, it means that the Authorization header is there and the token starts with Bearer and it is also not zero, am I right?
Please create a video of how to implement the refresh token, thanks for your work.
@BoualiAli
Жыл бұрын
Working on it
Thanks for the video, a lot of useful info in it! One question though, is with JWT tokens since they are stateless logout part on backend really necessary? Can it present any security issue or is it just enough to stop user from accessing secured resources if it is handled on frontend, invalidated there or deleted from local storage?
@BoualiAli
Жыл бұрын
It is also enough to delete it from local storage in the frontend. But this a double check and total logout and revoking the token. Many have request such functionality, so I answered the call 😁
@antoniodevic8704
Жыл бұрын
@@BoualiAli Thanks for the quick answer! Sure, double check can't definitely hurt :D
Thanks for the video! I just didn't understand why we need to create a token during registration. and what about the refresh token?
@BoualiAli
Жыл бұрын
The token in the registration is just to avoid re logging Refresh token will come soon
why did you use inner join when trying to fetch the tokens in 16.56 ? you can do it without making use of joins !! also you said you want the expired and revoked should equal to false and then using or how that?
Great videos! Can you do some on Spring Authorization Server by any chance?
@BoualiAli
Жыл бұрын
I will make one
Great video! could i replace token with jti?
@BoualiAli
11 ай бұрын
Yes you can!
Thank you for the video! I have a question. When I log out, Are the tokens just left permanently in the database? I am curious about what processing is common in a practical environment.
@BoualiAli
2 ай бұрын
you can create a script to clean the DB. By the way, Better use keycloak I will release a new video next week
Amazing video ,it was so helpful, My question is why we don't delete the old token instead of setting it expired
@BoualiAli
Жыл бұрын
Thank you. You can set a bash script to cleanup the database every period of time.
16:50 The query will return the tokens for the user that are either not expired or not revoked which means that will include tokens that are expired but not revoked, as well as tokens that are revoked but not expired. Was that the intention or we should return tokens that are neither expired nor revoked? For example instead of: ``` where u.id =:userId and (t.expired = false or t.revoked = false) ``` We can return non-expired and non-revoked tokens: ``` where u.id = :userId and t.expired = false and t.revoked = false ```
@ahmetyasinozturk-uu4wd
2 ай бұрын
I think that was a mistake. It should be non expired and non revoked token at the same time as you say.
Amazing work! Just a question, why we generate jwt token both in register and the authenticate methods? In my understanding, in register the token is generated and then in each coming request user must pass the jwt token. Also, I thought that one user has only one token associated with him, so the relationship between user-token should be one-to-one and not one-to-many? Thanks
@BoualiAli
9 ай бұрын
Totally true what you said. Just as I mentioned in the video, it is just for the tutorial to have a token after registration. But in real life no need for it. Feel free to adjust ass you need
great video @Ali Bouali. I have a question. For you what is best for implementing jwt between custom jwt like you did or use Oath2 resource server which hold jwt implementation. In the last case how to implement logout? Thanks
@BoualiAli
Жыл бұрын
Both of them are jwt based. You can use both of them I’m working on a new course that covers both, jwt and oauth 2 with a frontend built with angular. I will publish the a waiting list soon enough so you can register and get discount
@hamidoubalde2517
Жыл бұрын
@@BoualiAli thanks
Very helpful video. I have only one question, maybe I don’t understand something, but why store expired tokens.
@BoualiAli
Жыл бұрын
You remove expired token. In a different context. You might use them for auditing and tracing (maybe)
Hi, are we updating the database accessToken expired parameter when the accessTokenExpiration time finish ?
@BoualiAli
Жыл бұрын
I didn’t get your question can you please elaborate more?
Thank you very much Bouali for your tutorials, I'm a big fan and they helped me a lot in the past. I have a question though, i've implemented the logout like you did in the tutorial and I'm using an angular client but I'm having trouble to make the post request to /api/auth/logout. Do I need to add thist in my controller? I can not invalidate the usertoken calling from the frontend. Does anyone else had this Problem and can help me out here?
@BoualiAli
7 ай бұрын
Can you give more dettails. How you call the endpoint?
Awesome tutorial. I have one big doubt, I've seen lots of peopke saying its not secure to store tokens in the database. I am wondering the reason why you are doing this?
@BoualiAli
Жыл бұрын
As I mentioned, there is no implicit implementation for logout (jwt) and that is one simple solution. You can performa a daily cleanup for revoked / invalid tokens from the database
@JasmineTrader-mw8ru
Жыл бұрын
@@BoualiAli yes i understand that. But i do not want to store the valid tokens in database either for security reasons. Can you suggest me a way to revoke a token in the backend? Id there anyway we can remove the jwt from security context holder?
Thanks for the video! Why do you have expired and revoked flags? From my point of view expired flag is useless and confuses, cause token might not be expired but only revoked. It's two independent states.
@BoualiAli
7 ай бұрын
I mentioned in the video that these flags might be helpful in the future. Maybe not in this tutorial
Hi Bouali - Thanks for the amazing videos on Jwt. My question - in the first video, why are you only checking that token belongs to the user and does not expire during validation? Where does the secret key and the signature plays a role during validation? Can't i just create my own token and map to a valid and it will still be marked as valid?
@BoualiAli
Жыл бұрын
Decoding the token uses the secret that you generated. And it should be a secret of course 😁 To have your answer, I would ask you to generate a random token with a different secret ( you can use jwt.io website for that) and pass it to the backend and then you will see if it passes or not. Reply to this comment with your feedback. Looking forward for the result 🤛
@MuhammadAli-rp9cz
Жыл бұрын
@@BoualiAli Tested an i got the error io.jsonwebtoken.security.SignatureException: JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted. It seems like during decoding - it is not base64 decoding the payload - rather decrypting the signature and extracting the subject from their - Thanks, exactly as you said
This was a great add on to the Spring Security with JWT video! Thanks so much! This works great when testing in Postman, but when I test it from a browser (using axios in React) I cannot seem to avoid CORS violations. I can use @CrossOrigin on my REST controllers. Is there a proper way to configure the logout CORS policy?
@EagleT869
Жыл бұрын
maybe can add this in your security config http.csrf().disable().cors().configurationSource(new CorsConfigurationSource() { @Override public CorsConfiguration getCorsConfiguration(HttpServletRequest request) { CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.setAllowedOrigins(Collections.singletonList("*")); config.setAllowedMethods(Collections.singletonList("*")); config.setAllowedHeaders(Collections.singletonList("*")); config.setExposedHeaders(Arrays.asList( "Authorization", "X-Total-Count", "Link", "Access-Control-Allow-Origin", "Access-Control-Allow-Credentials" )); return config; }}).and()
@BoualiAli
Жыл бұрын
You just need to add a cors bean