Jwt 토큰을 이용한 인증 방식은 매 요청때마다 인증을 해야 하는 수고스러움이 있다.
이것을 서비스에서 매번 인증하지 않고 SecurityFilter 를 이용 하여 커스텀한 JwtAuthFilter 로 인증, 인가를 한번에 처리 할 수 있다.
.authorizeHttpRequests()
.antMatchers("/api/user/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(new JwtAuthFilter(jwtUtil), UsernamePasswordAuthenticationFilter.class);
@Slf4j
@RequiredArgsConstructor
public class JwtAuthFilter extends OncePerRequestFilter {
private final JwtUtil jwtUtil;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String token = jwtUtil.resolveToken(request);
if(token != null) {
if(!jwtUtil.validateToken(token)){
jwtExceptionHandler(response, "Token Error", HttpStatus.UNAUTHORIZED.value());
return;
}
Claims info = jwtUtil.getUserInfoFromToken(token);
setAuthentication(info.getSubject());
}
filterChain.doFilter(request,response);
}
public void setAuthentication(String username) {
SecurityContext context = SecurityContextHolder.createEmptyContext();
Authentication authentication = jwtUtil.createAuthentication(username);
context.setAuthentication(authentication);
SecurityContextHolder.setContext(context);
}
변경 전
@Override
@Transactional
public void deleteComment(Long id, HttpServletRequest request) {
String token = jwtUtil.resolveToken(request);
Claims claims = null;
if (token != null) {
if (jwtUtil.validateToken(token)) {
claims = jwtUtil.getUserInfoFromToken(token);
} else {
throw new IllegalArgumentException("Token error!");
}
}
User user = userRepository.findByUsername(claims.getSubject()).orElseThrow(
() -> new IllegalArgumentException("사용자가 존재하지 입니다. ")
);
Comment comment = commentRepository.findById(id).orElseThrow(
() -> new IllegalArgumentException("해당하는 댓글이 없습니다.")
);
validateComment(comment, user);
commentRepository.deleteById(id);
}
변경 후
@Override
@Transactional
public void deleteComment(Long id, User user) {
Comment comment = commentRepository.findByIdAndUserId(id,user.getId()).orElseThrow(
() -> new IllegalArgumentException("해당하는 댓글이 없습니다.")
);
validateComment(comment, user);
commentRepository.deleteById(id);
}
public interface CommentRepository extends JpaRepository<Comment,Long> {
Optional<Comment> findByIdAndUserId(Long id, Long id1);
}
변경 전
@DeleteMapping("/{id}")
public ResponseEntity deleteComment(@PathVariable Long id, HttpServletRequest request) {
commentServiceImpl.deleteComment(id,request);
return ResponseEntity.ok("댓글 삭제 완료");
}
변경 후
@DeleteMapping("/{id}")
public ResponseEntity deleteComment(@PathVariable Long id, @AuthenticationPrincipal UserDetailsImpl userDetails) {
commentServiceImpl.deleteComment(id,userDetails.getUser());
return ResponseEntity.ok("댓글 삭제 완료");
}