Implement token blacklist for JWT logout support
- TokenBlacklistService tracks invalidated tokens using Caffeine cache. - AuthController adds tokens to blacklist on logout. - JwtAuthenticationFilter blocks blacklisted tokens during authentication.
This commit is contained in:
@@ -4,6 +4,9 @@ import com.skycrate.backend.skycrateBackend.dto.LoginRequest;
|
||||
import com.skycrate.backend.skycrateBackend.security.JwtService;
|
||||
import com.skycrate.backend.skycrateBackend.entity.User;
|
||||
import com.skycrate.backend.skycrateBackend.repository.UserRepository;
|
||||
import com.skycrate.backend.skycrateBackend.security.TokenBlacklistService;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
@@ -48,9 +51,19 @@ public class AuthController {
|
||||
return ResponseEntity.ok().body(token);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private TokenBlacklistService tokenBlacklistService;
|
||||
|
||||
@PostMapping("/logout")
|
||||
public ResponseEntity<?> logout() {
|
||||
// Client-side token deletion (or implement blacklist)
|
||||
return ResponseEntity.ok("Logged out (client should delete token)");
|
||||
public ResponseEntity<?> logout(HttpServletRequest request) {
|
||||
String authHeader = request.getHeader("Authorization");
|
||||
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
|
||||
return ResponseEntity.badRequest().body("Missing or invalid Authorization header");
|
||||
}
|
||||
|
||||
String token = authHeader.substring(7);
|
||||
tokenBlacklistService.blacklistToken(token);
|
||||
|
||||
return ResponseEntity.ok("Logged out successfully");
|
||||
}
|
||||
}
|
||||
+13
-1
@@ -20,10 +20,14 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
|
||||
private final JwtService jwtService;
|
||||
private final UserRepository userRepository;
|
||||
private final TokenBlacklistService tokenBlacklistService;
|
||||
|
||||
public JwtAuthenticationFilter(JwtService jwtService, UserRepository userRepository) {
|
||||
public JwtAuthenticationFilter(JwtService jwtService,
|
||||
UserRepository userRepository,
|
||||
TokenBlacklistService tokenBlacklistService) {
|
||||
this.jwtService = jwtService;
|
||||
this.userRepository = userRepository;
|
||||
this.tokenBlacklistService = tokenBlacklistService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -42,6 +46,14 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
}
|
||||
|
||||
jwt = authHeader.substring(7);
|
||||
|
||||
// Check if token is blacklisted
|
||||
if (tokenBlacklistService.isTokenBlacklisted(jwt)) {
|
||||
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
response.getWriter().write("Token has been blacklisted");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
userEmail = jwtService.extractUsername(jwt);
|
||||
} catch (Exception e) {
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.skycrate.backend.skycrateBackend.security;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Service
|
||||
public class TokenBlacklistService {
|
||||
|
||||
private final Cache<String, Boolean> blacklistCache;
|
||||
|
||||
public TokenBlacklistService() {
|
||||
this.blacklistCache = Caffeine.newBuilder()
|
||||
.expireAfterWrite(1, TimeUnit.HOURS)
|
||||
.build();
|
||||
}
|
||||
|
||||
public void blacklistToken(String token) {
|
||||
blacklistCache.put(token, true);
|
||||
}
|
||||
|
||||
public boolean isTokenBlacklisted(String token) {
|
||||
return blacklistCache.getIfPresent(token) != null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user