--현재 문제점 --
시큐리티 사용으로 인해 사용자의 정보를 시큐리티컨텍스트 홀더에 저장
사용자의 정보가 필요한 작업 -> 장바구니 클릭 시 로그인된 사용자의 Id를 가져와 해당 사용자의 장바구니를 표현
장바구니 버튼을 통해서 사용자의 userId를 활용해서 로그인한 사용자의 장바구니 정보로 장바구니 조회시도
로그인을 했지만 조회할때 사용자 아이디가 NULL 반환, 로그인정보가 시큐리티 컨텍스트 홀더에 저장되어있는 것도 확인
--문제점 상세--
컨트롤러단에서 로그인한 유저의 정보를 SecurityContextHolder에 저장
SecurityContextHolder에 저장된 유저의 정보중 userId를 가져오려 시도했지만
시큐리티의 userDetails와 엔티티 user간의 충돌 발생
필요한 정보는 시큐리티의 정보인데 엔티티는 db관련 정보이기때문에
시큐리티가 생성하는 인증객체와
db엔티티간 혼동 발생 -> null처리로 반환됨
--해결시도 1--
@AuthenticationPrincipal 어노테이션으로 컨텍스트 홀더 데이터 접근시도 -> null
--해결시도 2--
컨트롤러 내 Authentication 객체를 생성후 SecurityContextHolder.getContext().getAuthentication();
컨텍스트 홀더에 저장된 내용을 직접 가지고와 그 내용중 필요한 데이터 가져오려 시도 -> Null반환
--해결시도 3--
- 시큐리티의 userDetail에는 getUserId 필드에 없으므로 사용자 정의 필요
- 시큐리티의 유저 디테일을 구현한 user구현체에
Getter메서드를 활용해서 userId를 사용자 정의 필드로 만들어서 사용 시도 - SecurityContextHolder.getContext().getAuthentication(); 호출 시 principal필드에 기본 구현체인 시큐리티 코어의 User를 반환함,
근데 컨트롤러는 이 객체를 User엔티티 객체로 캐스팅 시도.
왜냐면 User에 userDetails를 구현했으니 당연히 user 임포트시 구현된 user로 임포트 했음
하지만 컨트롤러는 필요한 시큐리티 객체가 아니라 엔티티의 객체를 반환 ->NULL
엔티티 클래스 User가 UserDetails를 구현했지만, Spring Security는 인증 객체로 엔티티 클래스를 직접 사용하지 않았슴
결과적으로 컨트롤러에서 기대하는 타입과 실제 반환된 타입 간에 불일치가 발생.
--해결시도 4 --
User 클래스를 시큐리티 코어의 user로 import해서 시도.
해당 구현체는 시큐리티 코어의 기본 구현체로 read Only 여기에는 userId정보도 없음 직접 구현 불가 -> userId get해오는것 자체가 불가능
--해결시도 5--
정석대로 엔티티의 User 역할과 분리해서 userDetailsImpl 작성해서 userDetails 구현체 작성으로
엔티티와 시큐리티 역할 분리. 작동시 역할 혼동을 없애서 정상작동유도
-> 작성한 코드가 ㅈㄴ 많네요 내가짠 코드가 아니라서 연관된거 고치다 자꾸 에러 발생 이거 고치다 포기함
--해결시도 6--
userDetailService에서 loadUserByUsername메서드에서 user객체에 반환할때 email, password, authorities만 반환하길래 추가로 user클래스의 userId도 반환하게 하려 시도
마찬가지로 여기서 반환되는 UserDetails 타입은 userDetails를 구현한 구현체여야 하는데 여기서도 user는 엔티티의 역할로 엔티티반환을 시도, 반대로 시큐리티 코어의 user를 반환하려 하면 이것은 시큐리티 코어에서 기본 구현체이기 떄문에 사용자 정의 사용 불가 -> userId 못뽑아옴
--해결 --
기본 코드를 수정하지 않고 컨트롤러 단에서 Authentication객체 생성 후 컨텍스트 홀더에 저장된
기본 userDetail에 정의된 email을 가져옴 (getUsername)
시큐리티 코어에 작성된 User를 기반으로 가져온 유저이메일을 엔티티로 작성된 유저 타입을 통해
유저매퍼를 사용해 이메일과 대치되는 유저 아이디를 엔티티 유저 타입으로 가져와서 userId에 저장
그다음 userId 사용
우선 시간이 없어서 임시방편으로 처리 했는데 컨트롤러 코드에 10+줄이 추가됨
-> 역할과 책임 분리가 안되서 컨트롤러에 엄청난 코드가 추가됨 ....
-> userDetailImpl을 구현해서 책임분리를 확실하게 해주면
@AuthenticationPrincipal UserDetailImpl userDetailImpl요놈 매개변수로 달아주고
userDetailImpl.getUesrId 하나면 이메일을 받아서 유저아이디로 매핑해서 쓸필요도 없이 바로 불러와짐
-- 결과--
개발자가 책임분리를 안해서 시스템은 필요로 하는 반환값을 제대로 인식하지 못했고
시스템 내부적으로 오인한 내용이라 에러도 하나도 안나옴. 로그뽑아서 확인해보니 컨텍스트 홀더에 로그인 내용이 분명 저장되는데 원하는값을 전혀 뽑아내지못함 계속 주구장창 NULL만 반환함 -> 오류도 안나옴 gpt는 시큐리티 설정 문제나 , 로그인 안한상태로 시도한거라고만 피드백줌 사람 미쳐버림
'Project > 회고' 카테고리의 다른 글
Docker caching (0) | 2025.05.16 |
---|---|
2025_04_28 프로젝트 에러 회고 (0) | 2025.04.28 |