이번 글은 '스프링 MVC 2(타임리프 섹션) - 김영한' 강의를 듣는 중
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>식 기본 객체 (Expression Basic Objects)</h1>
<ul>
<li>request = <span th:text="${#request}"></span></li>
<li>response = <span th:text="${#response}"></span></li>
<li>session = <span th:text="${#session}"></span></li>
<li>servletContext = <span th:text="${#servletContext}"></span></li>
<li>locale = <span th:text="${#locale}"></span></li>
</ul>
<h1>편의 객체</h1>
<ul>
<li>Request Parameter = <span th:text="${param.paramData}"></span></li>
<li>session = <span th:text="${session.sessionData}"></span></li>
<li>spring bean = <span th:text="${@helloBean.hello('Spring!')}"></span></li>
</ul>
</body>
</html>
다음과 같은 코드에서 출발했다.
💡 타임리프 3.1+에서
`${#request}`
`${#response}`
`${#session}`
`${#servletContext}`
코드들은 동작하지 않는다. SSR 렌더링인 타임리프에서 request나 session에 접근해 화면에 렌더링할 수 있는데, 개발자가 이런 코드를 실수로 작성한다면 의도하지 않은 데이터를 공개하게 된다.
따라서, model에 각 정보를 `addAttribute()`하고 사용해야 한다.
일반적으로 서버는 클라이언트에게 response(응답)을 보낸다. 하지만 이 코드를 실행했을 때, 화면은 request, response, session의 정보를 모두 렌더링한다. 어떻게 이게 가능할까?
SSR에서 Session 정보 전달 방식

Spring에선 Dispatcher Servlet이 View 구현체를 찾아서 적절한 View 구현체가 화면을 렌더링한다.

ThymeleafView는 Dispatcher Servlet에게 model, request, response를 인자로 받는다. 그렇기 때문에, `request.getSession()`을 통해서 request, response, session 모두 접근이 가능하다.
쉽게 설명하면, SSR은 서버에서 화면을 렌더링하고 해당 html을 response에 포함하기 때문에 request, response, session에 모두 접근이 가능하다.
반면, CSR은 RESTful API를 사용하기 때문에 보통 JSON 형식으로 통신한다. 그렇다면, CSR에선 response만 받는 것이 자명하다. SSR에선 request에 있는 session 정보를 꺼내 썼는데, CSR에선 어떻게 session 정보를 전송할까?
CSR에서 Session 정보 전달 방식
CSR에서는 session 정보를 클라이언트에게 전달하기 위해 서버가 명시적으로 가공해서 JSON으로 응답해야 한다.
@RestController
public class UserApiController {
@GetMapping("/api/user-info")
public ResponseEntity<UserInfoResponse> getUserInfo(HttpSession session) {
// Session에서 필요한 데이터만 추출
UserInfoResponse response = new UserInfoResponse();
response.setUserId((String) session.getAttribute("userId"));
response.setUsername((String) session.getAttribute("username"));
response.setRole((String) session.getAttribute("role"));
response.setSessionId(session.getId());
return ResponseEntity.ok(response);
}
}
이 때, session ID는 Cookie로 전달된다.
HTTP Response Headers:
Set-Cookie: JSESSIONID=ABC123; Path=/; HttpOnly
Response Body:
{
"userId": "john123",
"username": "John Doe",
"role": "USER"
}
| 구분 | SSR | CSR |
| 세션 ID | Cookie(자동) | Cookie(자동) |
| 세션 데이터 | 서버에서 HTML 렌더링 | 서버가 JSON으로 가공 |
결론적으로, SSR에서는 View 구현체가 서버 객체에 직접 접근할 수 있어 request, response, session 정보를 모두 화면에 렌더링할 수 있다. 하지만 이는 의도하지 않은 데이터 노출 위험을 가져왔고, Thymeleaf 3.1+에서는 보안을 강화했다.
CSR에서는 서버가 명시적으로 선별한 데이터만 JSON으로 전달하므로, 보안 관점에서 더 안전하지만 개발자가 세션 데이터를 수동으로 가공해야 하는 번거로움이 있다.
'Spring' 카테고리의 다른 글
| [Spring] 간단한 DTO ↔ Entity 변환에도 Mapper가 필요할까? (1) | 2025.08.19 |
|---|---|
| [Spring] @ExceptionHandler와 @ControllerAdvice에 관하여 (1) | 2025.07.14 |
| [Spring] @Component와 그 친구들(@Controller, @Service, @Repository, @Configuration) (0) | 2025.03.20 |
| [Spring] @Controller vs @RestController (0) | 2024.09.27 |