Skip to content

Conversation

Oh-Myeongjae
Copy link
Collaborator

@Oh-Myeongjae Oh-Myeongjae commented Oct 15, 2025

요구사항

✅ 기본

🛠 Spring Security 환경설정

  • 프로젝트에 Spring Security 의존성을 추가하세요.
  • Security 설정 클래스를 생성하세요.
    • 패키지명: com.sprint.mission.discodeit.config
    • 클래스명: SecurityConfig
  • SecurityFilterChain Bean을 선언하세요.
  • 가장 기본적인 SecurityFilterChain을 등록하고, 이때 등록되는 필터 목록을 디버깅해보세요.
    필터 목록은 PR에 첨부하세요.
  • 개발 환경에서 Spring Security 모듈의 로깅 레벨을 trace로 설정하세요.
    각 요청마다 통과하는 필터 목록을 확인할 수 있습니다.

🔒 CSRF 보호 설정하기

디스코드잇은 CSR 방식이기 때문에 CSRF 토큰은 다음과 같이 처리합니다.

  • 클라이언트에서 페이지가 로드될 때 CSRF 토큰 발급 API를 명시적으로 호출

  • 서버는 CSRF 토큰을 응답 헤더(Set-Cookie)를 통해 쿠키에 저장

  • 클라이언트에서 매 요청마다 쿠키에 저장된 CSRF 토큰을 헤더(X-XSRF-TOKEN)에 포함

  • 서버는 요청 헤더에 포함된 두 토큰 값(X-XSRF-TOKEN, Cookie)을 비교해 유효성 검증

  • CsrfTokenRepository 구현체를 CookieCsrfTokenRepository로 설정하세요.
    디폴트 구현체는 HttpSessionCsrfTokenRepository입니다.
    이때 클라이언트에서 쿠키에 저장된 CSRF 토큰에 접근해야 하므로 Http Only는 false로 설정합니다.

  • CsrfTokenRequestHandler 컴포넌트를 대체하세요.
    Spring 공식문서에서 권장하는 CSR+SPA 환경에 적합한 구현체를 정의하세요.

  • CSRF 토큰을 발급하는 API를 구현하세요.

    • 엔드포인트: GET /api/auth/csrf-token
    • 요청: 없음
    • 응답: 203 Void

👤 회원가입

  • 회원가입 API 스펙은 유지합니다.
    • 엔드포인트: POST /api/users
    • 요청: Body UserCreateRequest, MultipartFile
    • 응답: 200 UserDto
  • 회원가입 시 비밀번호는 PasswordEncoder를 통해 해시로 저장하세요.
    PasswordEncoder의 구현체는 BCryptPasswordEncoder를 활용하세요.

🔐 인증 - 로그인

  • formLogin 을 기본값으로 활성화하고, 추가된 필터를 확인해보세요.
  • 로그인 URL을 /api/auth/login으로 설정하세요.
  • UserDetailsService 컴포넌트를 대체하세요.
    DiscodeitUserDetailsService를 정의하세요.
  • UserDetails 컴포넌트를 대체하세요.
    DiscodeitUserDetails를 정의하세요.
  • AuthenticationSuccessHandler를 LoginSuccessHandler로 대체하세요.
  • AuthenticationFailureHandler를 LoginFailureHandler로 대체하세요.
  • 기존의 로그인 관련 코드를 제거하세요.
    (AuthApi.login, AuthController.login, AuthService.login, LoginRequest)

🧑‍💻 인증 - 세션을 활용한 현재 사용자 정보 조회

  • 세션ID를 통해 사용자의 기본 정보(UserDto)를 가져올 수 있도록 API를 정의하세요.
    • 엔드포인트: GET /api/auth/me
    • 요청: Cookie: JSESSIONID=…
    • 응답: 200 UserDto

🚪 인증 - 로그아웃

  • 로그아웃을 처리할 URL을 /api/auth/logout으로 설정하세요.
  • LogoutSuccessHandler 컴포넌트를 HttpStatusReturningLogoutSuccessHandler로 대체하세요.
    204 Void 응답을 반환하세요.

🔑 인가 - 권한 정의

  • 관리자(ADMIN), 채널 매니저(CHANNEL_MANAGER), 일반 사용자(USER) 권한을 정의하세요.
  • 회원 가입 시 모든 사용자는 USER 권한을 기본 권한으로 설정하세요.
  • 사용자 권한 수정 API를 구현하세요.
    • 엔드포인트: PUT /api/auth/role
    • 요청: Body UserRoleUpdateRequest
    • 응답: 200 UserDto
  • 어드민 계정이 없는 경우 ADMIN 권한을 가진 계정을 초기화하세요.

🧭 인가 - 권한 적용

  • authorizeHttpRequests를 활성화하고, 모든 요청을 인증하도록 설정하세요.
  • 다음 요청은 인증하지 않도록 설정하세요.
    • Csrf Token 발급
    • 회원가입
    • 로그인
    • 로그아웃
    • Swagger, Actuator 등
  • Method Security를 활성화하세요.
  • Service의 메소드별로 권한을 수정하세요.
    • 퍼블릭 채널 관리 → CHANNEL_MANAGER
    • 사용자 권한 수정 → ADMIN
  • 적절한 권한이 없는 경우 403 응답을 반환하세요.
  • RoleHierarchy를 활용해 권한의 계층 구조를 정의하세요.
    (관리자 > 채널 매니저 > 일반 사용자)

⚙️ 심화

세션 관리 고도화

  • 동일한 계정으로 동시 로그인할 수 없도록 설정하세요.
  • DiscodeitUserDetails의 equals(), hashCode()를 오버라이딩하세요.
  • 권한이 변경된 사용자의 세션을 무효화하세요.
  • UserStatus 엔티티 대신 SessionRegistry를 활용해 로그인 여부를 판단하도록 리팩토링하세요.
  • HttpSessionEventPublisher를 Bean으로 등록하세요.

로그인 고도화 - RememberMe

  • remember-me 파라미터가 true인 경우 세션이 만료되어도 자동 로그인되도록 설정하세요.
  • 로그인 유지 기능이 정상 작동하는지 확인하세요.
    (JSESSIONID 삭제 후 새로고침 시 인증 유지)

권한 적용 고도화

  • SpEL을 활용해 Method Security 기반 리소스 보호 정책을 강화하세요.
    • 사용자 정보 수정, 삭제 → 본인만 가능
    • 메시지 수정, 삭제 → 작성자만 가능

멘토에게

  • 셀프 코드 리뷰를 통해 질문 이어가겠습니다.

@Oh-Myeongjae Oh-Myeongjae changed the title sprint9 과제제출 [오명재] Sprint9 Oct 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant