컴퓨터 프로그래밍/Spring

[Spring] AuthFilter 예시 코드 분석

한33 2024. 9. 21. 14:50

package com.sparta.sweethoney.filter;

import com.sparta.sweethoney.domain.user.entity.User;
import com.sparta.sweethoney.domain.user.repository.UserRepository;
import com.sparta.sweethoney.util.JwtUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.IOException;

@Slf4j(topic = "AuthFilter")
@Component
public class AuthFilter implements Filter {
    private final UserRepository userRepository;
    private final JwtUtil jwtUtil;

    public AuthFilter(UserRepository userRepository, JwtUtil jwtUtil) {
        this.userRepository = userRepository;
        this.jwtUtil = jwtUtil;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String url = httpServletRequest.getRequestURI();

        if ("POST".equalsIgnoreCase(httpServletRequest.getMethod()) &&
                StringUtils.hasText(url) &&
                (url.startsWith("/users") || url.startsWith("/users/login"))) {
            chain.doFilter(request, response); // 다음 Filter 로 이동
        } else {
            // 나머지 API 요청은 인증 처리 진행
            // 토큰 확인
            String tokenValue = httpServletRequest.getHeader(jwtUtil.AUTHORIZATION_HEADER);

            if (StringUtils.hasText(tokenValue)) { // 토큰이 존재하면 검증 시작
                // JWT 토큰 substring
                String token = jwtUtil.substringToken(tokenValue);

                // 토큰 검증
                if (!jwtUtil.validateToken(token)) {
                    throw new IllegalArgumentException("Token Error");
                }

                // 토큰에서 사용자 정보 가져오기
                Claims info = jwtUtil.getUserInfoFromToken(token);
                Long userId = Long.valueOf(info.getSubject());
                User user = userRepository.findById(userId).orElseThrow(() ->
                        new NullPointerException("Not Found User")
                );

                request.setAttribute("userId", user.getId());
                request.setAttribute("userName", user.getUserName());
                request.setAttribute("email", user.getEmail());
                request.setAttribute("userRole", user.getUserRole());
                chain.doFilter(request, response); // 다음 Filter 로 이동
            } else {
                throw new IllegalArgumentException("Not Found Token");
            }
        }
    }

}

if ("POST".equalsIgnoreCase(httpServletRequest.getMethod()) &&
        StringUtils.hasText(url) &&
        (url.startsWith("/users") || url.startsWith("/users/login"))) {
    chain.doFilter(request, response); // 다음 Filter 로 이동

 

URL 요청이 POST 인 것 중에 /users 로 시작하거나, /users/login 으로 시작하는 건 그냥 바로 doFilter 를 실행시켜서 

통과시킨다.

if (StringUtils.hasText(url) &&
        (url.startsWith("/api/user/signup") || url.startsWith("/api/user/login"))
) {
    chain.doFilter(request, response); // 다음 Filter 로 이동
}

 


String tokenValue = httpServletRequest.getHeader(jwtUtil.AUTHORIZATION_HEADER);

if (StringUtils.hasText(tokenValue)) { // 토큰이 존재하면 검증 시작
    // JWT 토큰 substring
    String token = jwtUtil.substringToken(tokenValue);
String tokenValue = httpServletRequest.getHeader(jwtUtil.AUTHORIZATION_HEADER);
String tokenValue = jwtUtil.getTokenFromRequest(httpServletRequest);

 

둘 다 토큰을 가져오는 방식인데, 아래는 이전 게시물의 getTokenFromRequest 를 사용하는 방법이고

위는 Header 에서 다이렉트로 토큰을 가져온다.

 

토큰이 있다면 substringToken 메서드를 이용해서 딱 토큰값만 가져온다.


// 토큰 검증
if (!jwtUtil.validateToken(token)) {
    throw new IllegalArgumentException("Token Error");
}

 

JwtUtil 에서 구현되어있는 유효성 검사를 통해서 token 을 검사한다.


// 토큰에서 사용자 정보 가져오기
Claims info = jwtUtil.getUserInfoFromToken(token);
Long userId = Long.valueOf(info.getSubject());
User user = userRepository.findById(userId).orElseThrow(() ->
        new NullPointerException("Not Found User")
);

 

가져온 토큰을 복호화한다. ( Claims )

복호화 진행한 토큰에서 userId 를 가져온다음, user 가 실제 존재하는지 검사한다.


request.setAttribute("userId", user.getId());
request.setAttribute("userName", user.getUserName());
request.setAttribute("email", user.getEmail());
request.setAttribute("userRole", user.getUserRole());
chain.doFilter(request, response); // 다음 Filter 로 이동

 

doFilter 를 통해 request 로 컨트롤러까지 전달시킬 데이터를 setter 를 통해 지정해준다.

'컴퓨터 프로그래밍 > Spring' 카테고리의 다른 글

[Spring] ApiResponse 예시 코드 분석  (0) 2024.09.21
[Spring] AuthUser 예시 코드 분석  (0) 2024.09.21
[Spring] JwtUtil 예시 코드 분석  (0) 2024.09.21
[Spring] Naver Open API  (0) 2024.09.18
[Spring] RestTemplate  (2) 2024.09.17