본문 바로가기

Java & Spring

Spring CSRF - Thymeleaf와 Fetch API

반응형

 

오늘은 간단하게 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를 구축이 완성되면 해당 내용은 큰 의미는 없을 것 같다.