목록으로
개발

Day 65 - SecurityChain

·5분 읽기
데브코스백엔드부트캠프프로그래머스

이 글은 2026년 06월 08일 작성된 글입니다.

오늘은 기존 API Key 인증 구조에서 Spring Security 기반 인증/인가 구조로 넘어가는 과정을 정리했다.
관리자 API, 권한 체크, Security Filter, 비밀번호 암호화, JWT Access Token 도입 흐름까지 학습했다.


1. 최신성이 필요한 데이터는 DB 조회가 필요하다

내 정보 조회처럼 항상 최신 데이터가 필요한 경우에는 토큰에 담긴 정보만 믿지 않고 DB를 다시 조회해야 한다.

Member member = memberService.findById(actor.getId())
        .orElseThrow(() -> new ServiceException("401-1", "존재하지 않는 회원입니다."));

토큰은 요청자를 식별하는 데 사용할 수 있지만, 닉네임이나 권한처럼 변경될 수 있는 정보는 DB에서 최신 상태를 확인하는 것이 안전하다.


2. 관리자용 API 구현

관리자 전용 회원 조회 API와 게시물 통계 API를 구현했다.

GET /api/v1/adm/members
GET /api/v1/adm/members/{id}
GET /api/v1/adm/posts/count

관리자 API는 일반 사용자 API와 구분하기 위해 /adm 경로를 사용했다.


3. 관리자 권한 체크

관리자 API는 관리자 권한을 가진 사용자만 접근할 수 있도록 제한했다.

.andExpect(status().isForbidden())
.andExpect(jsonPath("$.resultCode").value("403-1"))
.andExpect(jsonPath("$.msg").value("권한이 없습니다."));

권한이 없는 사용자가 관리자 API를 호출하면 403 Forbidden 응답을 반환한다.


4. 인증과 인가

인증은 요청을 보낸 사용자가 누구인지 확인하는 과정이다.

이 요청을 보낸 너는 누구니?

인가는 인증된 사용자가 해당 URL에 접근할 권한이 있는지 확인하는 과정이다.

너는 이 API에 접근할 권한이 있니?

스프링 시큐리티에서 말하는 인가는 주로 URL 접근 권한 체크를 의미한다.


5. Spring Security 설치

Spring Security 의존성을 추가했다.

implementation("org.springframework.boot:spring-boot-starter-security")
testImplementation("org.springframework.security:spring-security-test")

Spring Security는 인증과 인가를 필터 기반으로 처리하는 보안 프레임워크다.


6. Spring Security 기본 동작

Spring Security를 추가하면 기본적으로 모든 요청을 보호한다.

즉, 별도 설정이 없으면 로그인하지 않은 사용자는 대부분의 요청에 접근할 수 없다.

REST API와 JWT를 사용하는 경우에는 프로젝트 방식에 맞게 직접 커스터마이징해야 한다.


7. Security 설정

REST API 프로젝트에 맞게 Security 설정을 수정했다.

csrf.disable();

또한 개발 편의를 위해 h2-console 접근을 허용했다.

REST API에서는 보통 세션 기반 폼 로그인이 아니라 토큰 인증을 사용하므로 CSRF 설정을 비활성화하는 경우가 많다.


8. CSRF와 SameSite

CSRF는 사용자가 의도하지 않은 요청을 브라우저가 대신 보내게 만드는 공격이다.

REST API에서는 보통 Authorization 헤더 기반 토큰 인증을 사용하고, 쿠키를 쓰더라도 SameSite 옵션을 함께 사용한다.

SameSite설명
None모든 요청에 쿠키 전송
Lax일부 크로스 사이트 GET 요청 허용
Strict같은 사이트 요청에만 쿠키 전송

9. Security Filter

Spring Security는 컨트롤러가 실행되기 전에 필터에서 먼저 동작한다.

요청
→ Security Filter
→ Controller

권한이 없으면 컨트롤러 액션 메서드는 실행되지 않는다.


10. 커스텀 인증 필터가 필요한 이유

Spring Security는 기본적으로 우리가 만든 JWT, apiKey, refreshToken 구조를 알지 못한다.

따라서 우리가 만든 인증 방식을 Spring Security가 이해할 수 있는 형태로 바꿔주는 커스텀 필터가 필요하다.

JWT / apiKey
→ CustomAuthenticationFilter
→ Spring Security 인증 객체

11. UsernamePasswordAuthenticationFilter 이전에 실행

커스텀 필터는 Spring Security의 기본 인증 필터보다 먼저 실행되도록 등록한다.

addFilterBefore(customAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)

이렇게 해야 이후 Security 과정에서 인증된 사용자로 판단할 수 있다.


12. 비밀번호 암호화

비밀번호는 복호화가 불가능한 방식으로 암호화해서 저장해야 한다.

로그인 시에는 사용자가 입력한 비밀번호를 같은 방식으로 암호화한 뒤 저장된 값과 비교한다.

입력 비밀번호 → 암호화 → 저장된 암호화 값과 비교

비밀번호 원문을 저장하지 않기 때문에 DB가 유출되어도 피해를 줄일 수 있다.


13. 로그 레벨

Spring Boot의 기본 로그 레벨은 INFO다.

개발이나 테스트 환경에서는 DEBUG 레벨로 낮추면 더 자세한 로그를 확인할 수 있다.

레벨설명
TRACE가장 상세
DEBUG개발/디버깅용
INFO일반 정보
WARN경고
ERROR에러

운영 환경에서는 보통 INFO 이상만 출력한다.


14. 인증이 필요 없는 요청은 패스

로그인, 회원가입, 공개 API처럼 인증이 필요 없는 요청은 커스텀 필터에서 통과시켜야 한다.

인증 필요 없음 → pass
인증 필요함 → accessToken / apiKey 검사

15. Access Token과 apiKey

기존 apiKey 방식은 매 요청마다 DB 조회가 필요했다.

SELECT * FROM member WHERE apiKey = ?

JWT 기반 Access Token을 사용하면 서버가 시크릿 키로 토큰을 검증할 수 있어 DB 조회 없이 인증할 수 있다.


16. Access Token과 Refresh Token

기존 apiKey는 Refresh Token 역할로 사용하고, JWT는 Access Token 역할로 사용할 예정이다.

구분Access TokenRefresh Token
수명짧음
DB 조회없음필요
폐기어려움가능
용도API 요청 인증Access Token 재발급

17. JWT 라이브러리 추가

JWT 처리를 위해 jjwt 라이브러리를 추가했다.

implementation("io.jsonwebtoken:jjwt-api:0.12.6")
runtimeOnly("io.jsonwebtoken:jjwt-impl:0.12.6")
runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.12.6")

18. JWT 생성에 필요한 정보

JWT를 만들기 위해서는 다음 정보가 필요하다.

  • SecretKey
  • 서명 알고리즘
  • Claims
  • 발급 시간
  • 만료 시간

Claims에는 사용자 id, username 같은 인증에 필요한 데이터를 담을 수 있다.


19. JWT는 암호화가 아니다

JWT는 암호화가 아니라 인코딩이다.

즉, 누구나 JWT 내용을 디코딩해서 확인할 수 있다.

JWT = Base64 인코딩된 토큰

따라서 비밀번호 같은 민감 정보는 절대 JWT에 넣으면 안 된다.


20. 순환참조 문제

커스텀 필터를 추가하는 과정에서 순환참조 문제가 발생했다.

customAuthenticationFilter
→ rq
→ memberService
→ securityConfig
→ customAuthenticationFilter

스프링은 순환참조를 기본적으로 허용하지 않기 때문에 의존성 구조를 재설계해야 한다.


✅ 정리

  • 관리자 API는 일반 API와 분리하고 관리자 권한 체크를 적용해야 한다.
  • Spring Security는 필터 기반으로 컨트롤러 실행 전에 인증과 인가를 처리한다.
  • REST API + JWT 구조에서는 커스텀 필터를 통해 Spring Security가 이해할 수 있는 인증 객체를 만들어야 한다.
  • 비밀번호는 복호화가 불가능한 방식으로 암호화해서 저장해야 한다.
  • Access Token은 DB 조회 없이 빠르게 인증할 수 있고, Refresh Token은 재발급과 폐기에 사용된다.
  • JWT는 암호화가 아니라 인코딩이므로 민감 정보를 담으면 안 된다.
  • 순환참조가 발생하면 빈 의존성 구조를 다시 정리해야 한다.
← 목록으로
데브코스백엔드부트캠프프로그래머스