Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: JWT User Principal 식별 로직 #77

Merged
merged 8 commits into from
Sep 29, 2024
Merged

Fix: JWT User Principal 식별 로직 #77

merged 8 commits into from
Sep 29, 2024

Conversation

loveysuby
Copy link
Member

@loveysuby loveysuby commented Sep 28, 2024

🚀 Related Issue

close: #76

📌 Tasks

  • User 식별 Access token payload 검증 필터를 추가했습니다.
  • Security 내 5xx 에러 발생 시 공통 응답에 wrapping 되도록 custom error 객체를 구현했습니다.

📝 Details

  • 이제 모든 인증 요청 (credential = true) 시 Security filter 내에서 항상 토큰을 해석합니다.

  • payload 내 유저 정보는 id, ROLE 만을 가집니다.

    • Feat: 내 정보 조회 API 구현 #33 을 용례로 parameter specification 수정하였습니다.
      • 토큰을 받는 API 파라미터 type : User -> Long 변경했습니다.
      • 이에 대한 논의점을 후술하였습니다.

📚 Remarks

Points or opinions to share teams

  • 현재 @UserAuthentication을 사용하는 모든 API 의 parameter type은 다음과 같습니다.
    public ToyouResponse<T> foo(@UserAuthentication User user)

문제사항 : User의 검증이 불확실한 상태로 Presentation Layer에 userId가 전달됩니다.

  1. payload 내 유저 정보는 id 만을 가지므로, User 객체의 실재여부는 인증 과정에서 확인되지 않습니다.
@Component
public class JWTAuthArgumentResolver implements HandlerMethodArgumentResolver {
	
	@Override
	public boolean supportsParameter(MethodParameter parameter)

	@Override
	public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
	                              NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
		return SecurityContextHolder.getContext()
				.getAuthentication()
				.getPrincipal();     // ex. 1 (userId 로 해석하나 User 존재 여부는 확인되지 않음)  
	}
}
  1. UserRepository에서 객체를 찾는 로직을 parameter type에 따라 선택해야 합니다.
  • User : JWTAuthArgumentResolver에서 조회 + 유효성 검증 후 Controller 전달

    • 검증의 목적이 분명해지나, 같은 유저가 여러 번 token을 넣고 요청하는 만큼 탐색하므로 복잡도가 커집니다.
      (Context, user verified event 등으로 처리할 수도 있습니다.)
  • Long: userId로 받고 API 내 service layer에서 검증

    • 해당 userId를 쓰는 경우에만 service에서 사용할 수 있습니다. 다만 인증 요구 API parameter를 모두 수정해야 합니다.

@loveysuby loveysuby added 🧾 API API feature 🐛 bug Fix a bug labels Sep 28, 2024
@loveysuby loveysuby self-assigned this Sep 28, 2024
@loveysuby loveysuby linked an issue Sep 28, 2024 that may be closed by this pull request
Copy link
Contributor

@woosung1223 woosung1223 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

작업 내용 확인했습니다~

그리고 아래의 논의점에 관한 부분은

UserRepository에서 객체를 찾는 로직을 parameter type에 따라 선택해야 합니다.
User : JWTAuthArgumentResolver에서 조회 + 유효성 검증 후 Controller 전달

검증의 목적이 분명해지나, 같은 유저가 여러 번 token을 넣고 요청하는 만큼 탐색하므로 복잡도가 커집니다.
(Context, user verified event 등으로 처리할 수도 있습니다.)
Long: userId로 받고 API 내 service layer에서 검증

해당 userId를 쓰는 경우에만 service에서 사용할 수 있습니다. 다만 인증 요구 API parameter를 모두 수정해야 합니다.

총 두 가지 이유로 Service Layer에서 User를 조회하는 것을 선호합니다.

  1. 프레젠테이션 레이어에서 더 이상 데이터 계층을 접근하지 않게 됨
  • 쿼리 발생 지역을 어플리케이션 레이어로만 국한시킬 수 있음
  • 데이터베이스까지의 네트워크 왕복 비용을 한번 더 줄일 수 있음 (1 RTT 감소)
  • 디버깅, 최적화 용이
  1. 검증은 필요한 곳에서만 해도 된다는 입장임
  • 서비스 규모가 커짐에 따라 검증은 과도하게 늘어날 수 있음
  • 불필요한 검증을 줄이는 것도 하나의 중요 요소라고 생각함

- SECURITY_GLOBAL_WHITELIST : 모든 사용자에게 인증 없이 접근 허용되는 경로를 관리한다.
- JWT_USER_AUTHENTICATION_WHITELIST : 토큰 기반의 사용자 인증만을 거치지 않고 접근 허용되는 경로를 관리한다.
@loveysuby
Copy link
Member Author

인증 방식을 세션에서 토큰으로 전환하는 과정이 꽤나 많은 부가작업이 수반되었네요. 🙄
저 역시도 2번 방법 (application layer DB 조회 수행 규격을 따름)이 더 명료하다고 생각합니다.

주요 도메인을 incoming request에서 persistence로 직접 찌르는 예외적 규칙이 생기는 것이 부자연스럽다고 느껴지네요.
관련 API 및 인증 경로 whitelist 추가 구성했습니다 ~

@woosung1223 woosung1223 merged commit c0936b7 into develop Sep 29, 2024
1 check passed
@woosung1223 woosung1223 deleted the fix/76 branch September 29, 2024 07:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🧾 API API feature 🐛 bug Fix a bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Fix] JWT User Principal 식별 로직
2 participants