문제1
로그인 할 때 로그인 요청한 관리자가 활성상태인지 확인하는데
이후에 로그인된 관리자가 뭔가 수정하거나 삭제할때도 활성상태인지 매번 확인하는게 좋은가
예를들어 관리자 A 가 로그인 할 때 활성상태였고, 몇몇 기능을 수행하다가
슈퍼관리자 B가 A를 비활성 또는 정지로 바꾸면
로그인 토큰이 유지되더라도 이후 기능을 수행할 수 없게 바꿔야할 거 같다

해결
로그인 때 활성화 여부는 Controller 단에서 Spring Security 가 확인함

Service 에서 다른 모든 기능을 수행할 때 Active 상태인지 확인을 다시 해주기
# 관리자 기능을 수행하려고 Transactional 에 들어오면 실행해서 확인
isActiveAdmin(getAdminById(userPrincipal.getId()));
# Admin 반환하는 로직
public Admin getAdminById(long adminId){
return adminRepository.findById(adminId).orElseThrow(
()->new ServiceException(ErrorCode.ADMIN_NOT_FOUND)
);
}
# 관리자가 활성상태가 맞는지 확인하는 로직
public void isActiveAdmin(Admin admin){
#isLoginable 은 활성(Active) 상태에서만 true 니까 활성상태가 아니라면 throw
if(!admin.getStatus().isLoginable()){
switch (admin.getStatus()) {
case PENDING -> throw new ServiceException(ErrorCode.ADMIN_PENDING); # 승인대기
case REJECTED -> throw new ServiceException(ErrorCode.ADMIN_REJECTED); # 신청 거부
case STOPPED -> throw new ServiceException(ErrorCode.ACCOUNT_STOPPED); # 정지
case INACTIVE -> throw new ServiceException(ErrorCode.ACCOUNT_INACTIVE); # 비활성화
default -> throw new ServiceException(ErrorCode.FORBIDDEN_ADMIN);
}
}
}
->
문제 2-1
Session 사용 로그인 -> JWT 사용 로그인으로 수정하며 든 의문...점
UserDetails 클래스를 SessionAdmin 클래스 대신 사용하는 느낌이라고 생각했음
정보의 일부를 상자에 담아 저장(DTO역할)
근데 왜 UserDetails 클래스는 Admin 객체 자체를 담고있는지... ... 담을거면 Session 처럼 최소한의 정보만 담는게 좋지 않나?
해결
일단 UserDetails 는 Spring Security 가 사용하는 표준 객체기 때문에 JWT 전용이 아님.... Session 에서도 사용한다!!!!
Session 이든 JWT 든 Spring Security 는 인증 사용자를 UserDetails 로 표시
방법이 여러개가 있음
| 저장방식 | Spring Security | 인증 정보 저장하는 틀 | DB 조회 (findXXById) | |
| 선택사항! | - Session - JWT |
기본으로 쓴다고 가정 | - DTO - UserDetails |
- 해도 되고 - 안 해도 됨 |
즉 Session 에서도 UserDetails 를 사용할 수 있음
-> Session + UserDetails 와 Session + sessionUserDTO 두개가 다를 뿐
| SessionUser (DTO) | UserDetails |
| 최소한의 필드를 가진 식별용 DTO 로 자주 사용 근데 Admin 에서 필요한 걸 다 가지고 있어도 상관 없음! 그럼 UserDetails 와의 차이는 Spring Security 호환성 뿐이다 |
인증 객체 (Admin 객체를 갖고 있는게 기본) |
Spring Security 에서 저장방식 (JWT, Session) 은 선택사항이지만
인증 저장 틀은 UserDetails 를 사용하는게 표준, 권장, 편리... 하다
면접Q) UserDetails 가 필수인가요? 또는 왜 저장할 때 UserDetails 를 사용했나요?
JWT 자체가 UserDetails 를 필수로 요구하지 않고 Session 에서도 SessionDTO 를 필수로 요구하지 않습니다.
하지만 Spring Security 는 UserDetails 를 기준으로 인증 객체를 관리하기 때문에
보안 인증을 구현 할 때 Spring Security 와 함께 구현한다면 UserDetails 를 사용하는것이 표준이고 권장되는 사항입니다.
추가로 UserDetails 를 기준으로 Spring Security 기능들이 동작하기 때문에
@AuthenticationPrincipal , @PreAuthorize("hasRole(' XXX ')"), SecurityContextHolder.getContext() 등을 편리하게 사용할 수 있습니다.
그럼 여기서 다시 한 번 Session 과 JWT 차이점 회기해보기 (DTO 사용 차이가 아닌 저장방식의 차이)
일단 Spring Security 인증 구조는 원래 공통적으로 아래 순서를 따르고
로그인 - UserDetails 저장 - SecurityContext 에 저장 - UserDetails 를 기준으로 인증 처리
-> 로그인 이후 모든 요청마다 UserDetails 라는 객체를 사용할 수 있음
( 권한 확인, 활성화 여부,,, Service 에서 식별 등등)
Session 과 JWT 차이는 그냥 UserDetails 를 어디서 가져오는지의 차이니까!
| Session | JWT | |
| 저장 | UserDetails 를 생성 후 Session 에 Security Context (UserDetails) 저장 |
UserDetails 를 생성 후 JWT 에 식별정보 (저장) |
| 인증 | Session 에서 UserDetails 를 꺼내서 인증 | JWT 파싱 UserDetailsService 로 UserDetails 다시 생성해서 인증 |
| 중요!!!! | 서버가 인증 정보 저장 | 클라이언트가 인증 정보 저장 |
면접Q) Session 과 JWT 차이가 뭔가요?
Session 은 로그인 시 UserDetails 를 TOMCAT 같은 WAS 메모리 의 Session 저장소에 저장하여 SessionId 가 들어오면 서버에서 ID 를 기준으로 저장된 UserDetails 를 보여주는 반면,
JWT 는 로그인 시 UserDetails 를 생성 후 해당 UserDetails 를 기반으로 JWT 만 발급 후 클라이언트가 시스템을 사용할 때 JWT 를 서버에 전달하고, 서버는 받은 JWT 를 파싱, 식별정보 추출, 추출된 정보를 기준으로 UserDetails 를 다시 생성하여 인증합니다.
면접Q) 왜 Session 대신 JWT 를 사용했나요?
세션은 사용자 인증 정보를 서버에서 저장하기때문에 서버가 증가할 경우 Session 공유를 위한 추가적인 관리가 필요합니다.
JWT 는 인증 정보를 저장하지 않기때문에 서버 메모리 사용량이 적고 수평 확장에 유리합니다.
이번 과제에서는 관리자 인증을 기반으로 상품 관리와 고객 관리 기능을 구현해야 했기 때문에, 향후 서비스 확장성을 고려하여 Stateless 구조인 JWT 방식을 선택했습니다.
하지만 관리자의 역할과 기능을 다루기 때문에 안정성 측면에서 JWT 를 어떻게 관리해야할지에 대한 추가적인 고민을 하게 되었고 토큰이 탈취되는 경우 즉시 차단할 수 없다는 단점을 보완하기 위해 Access Token 의 만료시간을 짧게 설정하고, Refresh Token 으로 재발급하도록 했습니다.
탈취 될 경우 사용할 수 있는 시간은 최소화 시키려고 노력했고, UX 를 유지할 수 있습니다.
결론
Session 쓰면 바로바로 차단할 수 있어서 보안쪽에서 장점을 가지는데
Token 은 차단이 어려움 -> Access Token 만료 시간을 짧게해서 탈취시 많이 못 쓰게 하고
Refresh Token 으로 진짜 사용자는 반복된 로그인으로 인한 불편함을 느끼지 않게 함 !!
SessionDTO 와 Session 방식을 혼란하여 공부해서 이해하는데 두배로 오랜 시간이 걸린것같다... 초반이 정말정말 중요하군아 ㅜ
문제 2-2
userDetails 에 Admin 객체가 이미 있는데 왜 비밀번호와 권한을 다른 매개변수로 보내야하는지 모르겠음
userDetails.getAdmin.getPassword 와 getRole 로 사용할 수 있는데 굳이 두 번 보내는 이유 ???
해결
Authentication 객체가 권한 정보를 직접 들고있어야함!
Spring Security 가 UserDetail (principal) 에 의존하지 않고 인증 객체를 만들 수 있어야함
Spring Security 는 인증 정보를 Authentication 객체로 관리
Authentication 에는 아래 필드가 포함됨
principal #사용자 -> userDetails
credentials # 비밀번호 -> 어떻게 인증했는지
authorities # 권한 목록 -> ROLE_XXX

권한을 체크할 때 principal.admin.role << 이렇게 하지 않고
실제 인증 상태를 확인 할 때 authentication.getAuthorities 로 확인하기 때문 / 굳이 principal 을 뜯어보지 않아도 됨
'SPARTA 과제 > TEAM | commerce' 카테고리의 다른 글
| 팀) 커머스 피드백 반영 (0) | 2026.03.08 |
|---|---|
| 팀) 커머스 - Soft Delete (0) | 2026.02.27 |
| 팀) 커머스 - DB 생성 시 값 넣기 (0) | 2026.02.27 |
| 팀) 커머스 - 리스트 출력 (0) | 2026.02.22 |
| 팀) 커머스 트러블슈팅 (2) (0) | 2026.02.20 |