1. 게시물에 번호 지정하기
1) 게시물 번호 공식 만들기
게시물 번호 = 전체 게시물 개수 - (현재 페이지 * 페이지당 게시물 개수) - 나열 인덱스
게시물 번호
- 최종 표시될 게시물 번호
전체 게시물 개수
- 데이터베이스에 저장된 게시물 전체 개수
현재 페이지
- 페이징에서 현재 선택한 페이지
페이지당 게시물 개수
- 한 페이지당 보여 줄 게시물의 개수
나열 인덱스
- for 문 안의 게시물 순서
- 현재 페이지에서 표시할 수 있는 게시물의 인덱스
- ex) 10개를 표시하는 페이지에서는 0~9, 2개를 표시하는 페이지에서는 0~1로 반복
2) 게시물 번호 공식 적용하기
templates/question_list.html
항목 | 설명 |
paging.getTotalElements | 전체 게시물 개수 |
paging.number | 현재 페이지 번호 |
paiging.size | 페이지당 게시물 개수 |
loop.index | 나열 인덱스 |
2. 답변 개수 표시하기
- 질문 목록 화면에서 해당 질문에 달린 답변 개수를 표시할 수 있는 기능
templates/question_list.html
- th:if="${#lists.size(question.answerList)>0}"로 답변이 있는지 조사하고, th:text="${#lists.size(question.answerList)}"로 답변 개수를 표시
3. 스프링 시큐리티란?
스프링 시큐리티(Spring Security)
- 스프링 기반 웹 애플리케이션의 인증과 권한을 담당하는 스프링의 하위 프레임워크
- 인증(authenticate)
-> 로그인과 같은 사용자의 신원을 확인하는 프로세스
- 권한(authorize)
-> 인증된 사용자가 어떤 일을 할 수 있는지(어떤 접근 권한이 있는지)
1) 스프링 시큐리티 설치
build.gradle
2) 스프링 시큐리티 설정
- 스프링 시큐리티는 기본적으로 인증되지 않은 사용자가 웹 서비스를 사용할 수 없게끔 만듬
- 스프링 시큐리티 기본 기능을 그대로 적용할 수 없으니까 따로 설정 필요
SecurityConfig.java
- 스프링 시큐리티의 설정을 담당
package com.example.demo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
//인증되지 않은 모든 페이지의 요청을 허락
http
.authorizeHttpRequests((authorizeHttpRequests)->authorizeHttpRequests
.requestMatchers(new AntPathRequestMatcher("/**")).permitAll());
return http.build();
}
}
@Configuration
- 이 파일이 스프링의 환경 설정 파일임을 의미
- 스프링 시큐리티를 설정하기 위해 사용
@EnableWebSecurity
- 모든 요청 URL이 스프링 시큐리티의 제어를 받도록 함
- 스프링 시큐리티를 활성화하는 역할
- 내부적으로 SecurityFilterChain 클래스가 동작하여 모든 요청 URL에 이 클래스가 필터로 적용되어 URL별로 특별한 설정을 할 수 있게 함
@Bean
- 스프링에 의해 생생 또는 관리되는 객체
- 컨트롤러, 서비스 ,리포지터리 등도 모두 빈에 해당
- 스프링 시큐리티의 세부 설정은 @Bean을 통해 SecurityFilterChain 빈을 생성하여 설정 가능
3) H2 콘솔 오류 수정
- 스프링 시큐리티를 적용하면 H2 콘솔 로그인 시 403 Forbidden 오류가 발생
403 Forbidden
- 작동 중인 서버에 클라이언트의 요청이 들어왔으나, 서버가 클라이언트의 접근을 거부했을 때 반환하는 HTTP 오류 코드 - 서버 또는 서버에 있는 파일 등에 접근 권한이 없을 경우에 발생
- 스프링 시큐리티의 CSRF 방어 기능에 의해 H2 콘솔 접근이 거부되기 때문
CSRF
- 웹 보안 공격 중 하나로, 조작된 정보로 웹 사이트가 실행되도록 속이는 공격 기술
- 스프링 시큐리티는 CSRF 토큰을 세션을 통해 발행하고, 웹 페이지에서는 폼 전송 시에 해당 토큰을 함께 전송하여 실제 웹 페이지에서 작성한 데이터가 전달되는지를 검증
- 만약 CSRF 토큰이 없거나 해커가 임의의 CSRF 토큰을 강제로 만들어 전송한다면 스프링 시큐리티에 의해 차단 될 것
- H2 콘솔은 스프링 프레임워크가 아니므로 CSRF 토큰을 발행하는 기능이 없어 403 오류 발생
SecurityConfig.java
- 스프링 시큐리티가 CSRF 처리 시 H2 콘솔은 예외로 처리
...
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorizeHttpRequests)->authorizeHttpRequests
.requestMatchers(new AntPathRequestMatcher("/**")).permitAll())
.csrf((csrf)->csrf
.ignoringRequestMatchers(new AntPathRequestMatcher("/h2-console/**")));
...
- h2 콘솔 로그인은 수행되나 화면이 깨져 보임
- H2 콘솔의 화면이 프레임(frame) 구조로 작성되었기 때문
- H2 콘솔은 UI 레이아웃이 이 화면 처럼 작업 영역이 나눠져 있음을 의미
- 스프링 시큐리티는 웹 사이트의 콘텐츠가 다른 사이트에 포함되지 않도록 하기 위해 X-Frame-Options 헤더의 기본값을 DENY로 사용하는데, 프레임 구조의 웹 사이트는 이 헤더의 값이 DENY인 경우 이와 같은 오류 발생
X-Frame-Options 헤더
- 클랙재킹 공격을 막기 위해 사용
- 클랙재킹 -> 사용자의 의도와 다른 작업이 수행되도록 속이는 보안 공격 기술
SecurityConfig.java
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
...
.headers((headers)->headers
.addHeaderWriter(new XFrameOptionsHeaderWriter(
XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN)));
return http.build();
}
}
- URL 요청 시 X-Frame-Options 헤더를 DENY 대신 SAMEORIGIN으로 설정하여 오류가 발생하지 않도록 함
- X-Frame-Options 헤더의 값으로 SAMEORIGIN을 설정하면 프레임에 포함된 웹 페이지가 동일한 사이트에서 제공할 때만 사용이 허락 됨
'SpringBoot' 카테고리의 다른 글
[Do it] 3장 스프링 부트 고급 기능 익히기(4) (1) | 2024.01.24 |
---|---|
[Do it] 3장 스프링 부트 고급 기능 익히기(3) (1) | 2024.01.23 |
[Do it] 3장 스프링 부트 고급 기능 익히기(1) (0) | 2024.01.22 |
[Do it] 스프링 부트 기본 기능 익히기(6) (1) | 2024.01.22 |
[Do it] 2장 스프링 부트 기본 기능 익히기(5) (0) | 2024.01.21 |