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 |