티스토리 뷰
✅ 전자정부 프레임워크에서 Invalid CSRF token found 오류 해결 방법
전자정부 프레임워크에서는 Spring Security의 CSRF (Cross-Site Request Forgery) 보호 기능이 활성화되어 있어,
POST 요청 시 유효한 CSRF 토큰이 없으면 Invalid CSRF token found 오류가 발생할 수 있습니다.
이 문제를 해결하는 방법을 정리해 보겠습니다.
🔹 1️⃣ CSRF 토큰을 폼에 추가하기
Spring Security를 사용하면, 폼을 제출할 때 CSRF 토큰이 포함되어야 합니다.
보통 POST 요청 시 CSRF 토큰이 없으면 Invalid CSRF token found 오류가 발생합니다.
✅ 해결 방법: <form:form> 내부에 CSRF 토큰 추가
(1) JSP에서 form:form 사용 시
<%@ taglib uri="http://www.springframework.org/security/tags" prefix="sec" %>
✅ <sec:csrfInput/>을 추가하면 CSRF 토큰이 자동으로 포함됨
(2) 일반 <form> 태그 사용 시
<form id="redOrganMemForm" action="/boffice/redwhistle/redOrganMemList.do" method="post">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> <!-- CSRF 토큰 추가 -->
<input type="text" name="name"/>
<input type="submit" value="제출">
</form>
✅ ${_csrf.parameterName}과 ${_csrf.token}을 활용하여 CSRF 토큰을 직접 추가
🔹 2️⃣ CSRF 토큰을 AJAX 요청에 추가하기
만약 AJAX로 POST 요청을 보낼 때 CSRF 토큰이 포함되지 않으면 오류가 발생할 수 있습니다.
✅ 해결 방법: AJAX 요청에 CSRF 토큰 포함하기
var csrfToken = $("meta[name='_csrf']").attr("content");
var csrfHeader = $("meta[name='_csrf_header']").attr("content");
$.ajax({
url: "/boffice/redwhistle/redOrganMemList.do",
type: "POST",
data: { name: "홍길동" },
beforeSend: function(xhr) {
xhr.setRequestHeader(csrfHeader, csrfToken); // CSRF 토큰 추가
},
success: function(response) {
alert("성공!");
},
error: function(xhr) {
alert("오류 발생: " + xhr.status);
}
});
✅ 설명
- CSRF 토큰은 보통 <meta> 태그로 전달되므로, $("meta[name='_csrf']").attr("content")로 가져와야 합니다.
- beforeSend에서 xhr.setRequestHeader(csrfHeader, csrfToken);을 설정하여 헤더에 CSRF 토큰을 추가해야 합니다.
✅ JSP에서 <meta> 태그 설정하기
<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>
✅ 이렇게 설정하면, 모든 AJAX 요청에서 CSRF 토큰을 쉽게 추가할 수 있음
🔹 3️⃣ CSRF 보호 기능 비활성화 (비추천 🚨)
CSRF 보호 기능을 비활성화하면 보안상 위험할 수 있습니다.
하지만 내부 개발 환경에서만 CSRF 검사를 일시적으로 비활성화할 수도 있습니다.
✅ Spring Security에서 CSRF 비활성화
security-context.xml에서 설정 (XML 방식)
<http>
<csrf disabled="true"/>
</http>
SecurityConfig.java에서 설정 (Java 방식)
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
🚨 주의:
- CSRF 보호 기능을 비활성화하면 보안에 취약해질 수 있음.
- CSRF 비활성화는 개발 환경에서만 사용하고, 운영 환경에서는 반드시 CSRF 보호를 유지할 것!
🔹 4️⃣ CSRF 예외 URL 추가하기
특정 요청에 대해서만 CSRF 검사를 제외할 수도 있습니다.
예를 들어, 로그인, 로그아웃, 특정 API 요청 등에 대해 CSRF 예외 처리가 가능합니다.
✅ Spring Security에서 특정 URL에 대해 CSRF 예외 처리
(1) security-context.xml에서 설정 (XML 방식)
<http>
<csrf>
<csrf-matcher type="none" pattern="/boffice/redwhistle/redOrganMemList.do"/>
</csrf>
</http>
✅ 특정 URL에 대해서만 CSRF 보호 기능을 비활성화
(2) SecurityConfig.java에서 설정 (Java 방식)
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf()
.ignoringAntMatchers("/boffice/redwhistle/redOrganMemList.do"); // CSRF 예외 처리
}
✅ 특정 URL에 대해서만 CSRF 보호를 제외할 수 있음
🔥 최종 정리
해결 방법 설명 추천 여부
<sec:csrfInput/> 추가 | Spring Security 태그를 사용하여 CSRF 토큰 자동 추가 | ✅ (권장) |
<input type="hidden"> 추가 | CSRF 토큰을 직접 폼에 추가 | ✅ (권장) |
AJAX 요청에 CSRF 토큰 추가 | xhr.setRequestHeader(csrfHeader, csrfToken); 사용 | ✅ (권장) |
CSRF 비활성화 | http.csrf().disable(); 설정 | ❌ (비추천, 보안 위험) |
특정 URL만 예외 처리 | http.csrf().ignoringAntMatchers("/some-url") | ⚠️ (일부 경우 가능) |
💡 가장 좋은 방법:
- 폼에 <sec:csrfInput/> 또는 hidden input을 추가
- AJAX 요청 시 CSRF 토큰을 헤더에 추가
- 로그인, 로그아웃 등 특정 URL에 대해서만 CSRF 예외 처리
🚀 운영 환경에서는 CSRF 보호를 유지하고, 개발 환경에서만 비활성화하는 것이 안전합니다!
'Skill > spring' 카테고리의 다른 글
spring] defaultErrorView 설정 (0) | 2025.04.05 |
---|---|
MyBatis <selectKey>를 사용하여 SEQUENCE 값을 가져오기 (0) | 2025.03.28 |
java] 메일 보내기 (0) | 2025.03.04 |
Query Timeout 적용 최종 (0) | 2025.01.13 |
SMTPConfig.java (0) | 2025.01.13 |
- Total
- Today
- Yesterday
- caniuse
- Keycode
- spring
- JQuery
- 진열사랑
- @ExceptionHandler
- element위치
- PostgreSQL
- devtools
- 전후방탐색
- lombok
- sumifs
- CSS
- 여러 컬럼 update
- DatePicker
- $.each
- setter
- object key
- QueryDSL
- getter
- ul li로 테이블
- excel
- 정규식
- 프로젝트명변경
- draw.io
- $.extend
- Javascript
- border-collapse
- springboot
- oracle
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |