[TIL] 23.01.13 JwtAuthFilter 로 인증, 인가 하기

hyewon jeong·2023년 1월 13일
0

TIL

목록 보기
68/138

1 . 문제점

Jwt 토큰을 이용한 인증 방식은 매 요청때마다 인증을 해야 하는 수고스러움이 있다.


2 . 시도한 점

이것을 서비스에서 매번 인증하지 않고 SecurityFilter 를 이용 하여 커스텀한 JwtAuthFilter 로 인증, 인가를 한번에 처리 할 수 있다.


3 . 해결

WebSecurityConfig

                .authorizeHttpRequests()
                .antMatchers("/api/user/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .addFilterBefore(new JwtAuthFilter(jwtUtil), UsernamePasswordAuthenticationFilter.class);

JwtAuthFilter


@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);
    }

CommentService 중

변경 전

    @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);

    }

commentRepository

public interface CommentRepository extends JpaRepository<Comment,Long> {
    Optional<Comment> findByIdAndUserId(Long id, Long id1);
}

commentController

변경 전

    @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("댓글 삭제 완료");
    }
profile
개발자꿈나무

0개의 댓글