I want to do so it's not necessary to pass the id or username in the request. I was doing it like this:
// In the controller
@DeleteMapping
public ResponseEntity<?> deleteStudent(@RequestHeader(name = "Authorization") String authHeader) {
studentService.deleteEstudiante(authHeader); // Pass the token into the service
return ResponseEntity.noContent().build();
}
// In the service
public void deleteStudent(String authHeader) {
String token = jwtService.getTokenFromAuthorizationHeader(authHeader).orElseThrow(
() -> new IllegalArgumentException("Invalid token")
);
String email = jwtService.getUsernameFromToken(token); // Get the subject
// Rest of the logic where I search the user by email in the repository and I delete it
}
But I figured that's wrong. Which is the correct way?
I can't say which approach is right, as I think this depends on individual preferences or requirements.
In my case, I use a JWT filter as shown below:
@Override
protected void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain
) throws ServletException, IOException {
String token = tokenParser.resolveToken(request);
if (token != null && !token.isBlank()) {
if (blackListRepository.existsByAccessToken(token)) {
throw new TokenExpiredException();
}
Authentication authentication = tokenParser.authentication(token);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
filterChain.doFilter(request, response);
}
Using this code, I register the following filter and execute it on a page that can only be accessed by logged-in users. The filter verifies the token and registers the current user in Spring Security's SecurityContextHolder.
And then, I use the following method:
public User getUser() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
AuthDetails authDetails = null;
if (authentication.getPrincipal() instanceof AuthDetails) {
authDetails = (AuthDetails) authentication.getPrincipal();
}
if (authDetails == null || authDetails.getPhone() == null) {
throw new BasicException(ErrorCode.TOKEN_NOT_VALID);
}
return userRepository.findByPhone(authDetails.getPhone()).orElseThrow(UserNotFoundException::new);
}
I retrieve the user from the SecurityContextHolder and use it.