반응형
오늘은 간단하게 CSRF Token을 처리하는 방법을 정리해보고자 한다.
기존 JSP를 거의 걷어내면서 약간씩 다르게 처리되는 부분이 있어 정리차원에서 글을 남긴다.
1. Thymeleaf : <form>
<form action="/login" method="post" name="loginForm">
<!-- 생략 -->
</form>
우선 평소처럼 작성을 하고 csrf token을 처리할 생각이었다.
하지만 찾아보니 기본적으로 thymeleaf의 기능을 활용하면 알아서 form 요청 시 hidden input에 토큰을 처리해준다고 한다.
크게 바꿀것은 없고 아래와 같이 작성해주면 된다.
<th:block th:fragment="headerFragment" />
<!-- 생략 -->
<form th:action="@{/login}" method="post" name="loginForm">
<!-- 생략 -->
</form>
thymeleaf에서 주소를 다룰 때 @{ ... } 방식을 사용하면 된다.
JSP의 EL 표기법처럼 ${ ... } 사용하는 것은 그대로이며, 두가지를 혼용하여 사용도 가능하다.
실제로도 input hidden이 추가된 것을 볼 수 있다. 아래 value에 token 값이 들어있다고 보면 된다.
<input type="hidden" name="_csrf" value=".....">
그럼 fetch api를 사용할 때는 어떻게 하면 될까?
2. Thymeleaf : Fetch API
우선 이 부분은 원래 아는 내용과 크게 다르지 않다.
아래와 같이 meta 태그 두개에 content 값을 넣어주고,
<html xmlns:th="http://www.thymeleaf.org">
<th:block th:fragment="headerFragment" />
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta id="_csrf" name="_csrf" th:content="${_csrf.token}">
<meta id="_csrf_header" name="_csrf_header" th:content="${_csrf.headerName}">
<!-- 생략 -->
</head>
<!-- 생략 -->
javascript 부분에서 불러와주면 된다.
const csrfHeader = document.querySelector('meta[name="_csrf_header"]').content;
const csrfToken = document.querySelector('meta[name="_csrf"]').content;
fetch(uri, {
method: "PATCH",
headers: {
"header": csrfHeader,
"X-CSRF-TOKEN": csrfToken,
"Content-Type": "application/json"
},
body: JSON.stringify({email:email})
}).then(resp => resp.json())
// 생략
해당 부분은 크게 어려운 점은 없어보인다.
다만 이후에 OAuth2 AuthorizationServer와 ResourceServer를 구축이 완성되면 해당 내용은 큰 의미는 없을 것 같다.