일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- .ppk
- 환경변수
- jwt 필터
- Quartz dependency
- Quartz 라이브러리
- ..gitignore
- 배포 자동화
- submit 기본동작
- Jenkins
- git 폴더 모으기
- vue 추가
- 깃허브 토큰 발급
- deploy.sh
- 깃허브 토큰 생성
- AWS 생성
- dbeaver 백업/복구
- 클래스 참조
- 테스팅
- CI/CD
- EL1021E
- 채팅 프로젝트
- 타임리프 참조 오류
- jwt 헤더
- reset
- options 처리
- 되돌리기
- prefilight
- 배열 call by value
- 소프트웨어
- vue 실행
- Today
- Total
lty's Blog
JWT 헤더 검증과 CORS 본문
1) JWT Authorization 헤더 값 전달
백엔드 서버에서 클라이언트의 요청이 유효한 요청인지 판별하기 위해 클라이언트에선 HTTP 헤더에 Authorization 값에 JWT 키값을 설정하여 백엔드 서버에 요청
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6...
* Bearer 문자열을 붙이는 것이 기술적으로는 필요 없지만 JWT 표준 준수, 호환성, 보안 필터 연동 위해 붙이는 것이 좋음(주로 요청이 잦은 액세스 토큰에만 사용)
2) JWT Filter에서 요청을 검증
한 번의 요청만 실행하는 OncePerRequestFilter 클래스를 상속받아 로직 작성
* JWT 검증을 인터셉터에서 사용하지 않는 이유
- 인증/인가는 가장 먼저 처리되어야 하며, 인터셉터는 그보다 나중에 작동하기 때문에 보안에 취약할 수 있어 필터에서 처리
3) Prefilight 요청 Filter에서 처리
JWT 토큰을 헤더(Authorization)에 넣어 백엔드 서버에 요청 시 Prefilight 요청이 발생하여 CORS에 걸리지 않게 하려면 OTPIONS 요청도 허용을 해줘야 한다.
* 참고 Prefilight 요청 조건 : CORS와 브라우저 prefilight 요청
CORS 와 브라우저 prefilight 요청
* CORS(Cross-Origin Resource Sharing) 란 브라우저에서 서로 다른 출처(origin) 간의 자원 요청을 제어하는 보안 정책* Origin 은 프로토콜, 호스트, 포트가 모두 같아야 같은 Origin으로 인식하고 다른 출처에
sunhistory.tistory.com
Spring WebMvcConfigurer CORS 설정으로 적용 시 필터보다 뒷단에 있어 CORS 설정이 적용되지 않는다.
* Filter에 도달 후 Dispatcher Servlet에 도달
@Configuration
@Description(description = "인터셉터 등 기본 웹 설정을 위한 클래스")
public class WebConfig implements WebMvcConfigurer {
@Value("${allow.client.domain}")
String allowDomain;
@Override
public void addInterceptors(InterceptorRegistry registry) {
.....
}
/* CORS 설정 */
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins(allowDomain) // CORS 허용 도메인
.allowedMethods("GET", "POST", "OPTIONS") // 허용할 메서드
.allowedHeaders("*") // 허용할 헤더 설정
.allowCredentials(true); // 쿠키나 보안적인 값을 전달 할지 여부
}
}
* Filter에서 JWT를 처리할 경우 JWT에서 OPTIONS 요청 처리를 해야 한다.
JWT FILTER
@Component
@RequiredArgsConstructor
public class JwtCheckFilter extends OncePerRequestFilter {
private final JwtUtil jwtUtil;
@Value("${allow.client.domain}")
String allowDomain;
@Override // 필터제외 설정
protected boolean shouldNotFilter(HttpServletRequest request){
return false;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
String headerStr = request.getHeader("Authorization");
/* preflight 요청 CORS 방지 */
response.setHeader("Access-Control-Allow-Origin", allowDomain);
response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type");
response.setHeader("Access-Control-Allow-Credentials", "true");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
return;
}
if(headerStr == null || !headerStr.startsWith("Bearer ")){
handle403Exception(response, "Not Found Token");
LoggingService.info(getClass(), "Not Found Token :" + headerStr);
return;
}
...................
}
private void handle403Exception(HttpServletResponse response, String error) throws IOException {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.setContentType("application/json");
response.getWriter().println("{\"error\": \"" + error+"\"}");
}
private void handle401Exception(HttpServletResponse response, String error) throws IOException {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType("application/json");
response.getWriter().println("{\"error\": \"" + error+"\"}");
}
}
'기타' 카테고리의 다른 글
CORS 와 브라우저 prefilight 요청 (0) | 2025.05.18 |
---|---|
정보처리기사 합격 후기 (0) | 2024.06.19 |
정보처리기사 실기 시험 전 확인해 볼 사항 정리 (0) | 2024.04.26 |
DBeaver Mysql데이터 백업/복구 (0) | 2024.02.24 |
프로세스와 쓰레드 (0) | 2024.02.17 |