-
Notifications
You must be signed in to change notification settings - Fork 5
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
[Feature] - 인가 구현 #79
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
안녕하세요 클로버 🍀
주말인데 고생많으셨습니다.
인가 방식에 대한 것과 나머지 간단한 코멘트 남겨드렸어요
방식을 정하고 넘어가면 좋을 것 같아 우선은 RC 남겨드립니다.
회의가 필요할 수도 있을 것 같군요 🤔
ps. 인가를 구현하신 것으로 확인했는데 PR제목과 코드에서 사용되는 여러 용어 검토 부탁드립니다
try { | ||
return Jwts.parserBuilder() | ||
.setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8)) | ||
.build() | ||
.parseClaimsJws(token) | ||
.getBody() | ||
.get(MEMBER_ID_KEY) | ||
.toString(); | ||
} catch (ExpiredJwtException exception) { | ||
throw new UnauthorizedException("이미 만료된 토큰입니다."); | ||
} catch (Exception exception) { | ||
throw new UnauthorizedException("유효하지 않은 토큰입니다."); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
try catch 사용하는 만큼 stackTrace를 확인할 수 있게 cause를 예외 생성시에 추가시켜 주세용
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반영 완료했심다 👍
@RequiredArgsConstructor | ||
@Slf4j | ||
@Component | ||
public class JwtAuthFilter extends OncePerRequestFilter { | ||
|
||
private final ObjectMapper objectMapper; | ||
private final JwtTokenProvider tokenProvider; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
필터를 운용할 필요가 있나 싶습니다.
ArgumentResolver를 운용하는 만큼 인가 과정을 ArgumentResolver에 맞기시는 것은 어떨까요?
이와 같이 구현하면 관리하기 힘든 화이트 리스트를 운용할 필요도 없고 서블릿 필터라는 굉장히 Low한 계층에 의존하고 있는 문제점을 제거할 수 있습니다!
ArgumentResolver가 JwtTokenProvider를 의존하도록 하고 인자가 resolve 될 때마다 인가하도록 처리하면 제가 말씀드린 방식의 구현이 됩니닷
인자가 붙어있는 컨트롤러 메서드에서만 인가가 이루어지도록 처리할 수 있쥬
클로버의 의견 들려주세요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interceptor로 변경하자는 의견이 아니라 ArgumentResolver에게 인가를 맡기자는거라면 반대입니당
인증되지 않은 사용자의 요청은 Handler까지 흘러들어와야 할 필요가 없다고 생각해요. 적어도 Interceptor를 통해 Handler가 불리기 이전에 blocking 되는게 리소스 낭비도 덜하고 보안적인 측면에서도 더 안전할 것 같습니다.
위의 이유로 MethodArguementResolver는 모든 메서드의 파라미터를 처리할 때 공통적으로 필요할 때 사용되는 기능이지 인증/인가를 위한 기능이라고 생각되지 않습니다. 🙇
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+) 추가로 화이트 리스트는 이후 더 늘어날 곳은 없어보입니다. 유지보수가 힘들 것 같지는 않아용!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 .. 몰랐던 시각이에요
클로버의 말 이해했고 충분히 합리적이라는 생각이 드네요.
다만 인터셉터 혹은 필터로 분리할 경우 인가과정이 두개의 스텝으로 진행되면서 한눈에 들어오지 않는 것도 사실 인 것 같아요.
그리고 리소스 낭비를 이야기 하셨는데 트랜잭션이 열리기 전에 요청이 반려된다면 리소스 낭비가 그렇게 심할지도 의문이긴 합니다.
저는 개인적으로 argumentResolver에서 한큐에 처리하고 싶다는 생각이기는 한데요, 제가 일반적인 방법을 모르고 있어서 저도 제 방식에 확신을 하지는 못합니다.
다 같이 얘기해보면 좋을 것 같아유!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
다만 인터셉터 혹은 필터로 분리할 경우 인가과정이 두개의 스텝으로 진행되면서 한눈에 들어오지 않는 것도 사실 인 것 같아요.
요 부분에 대해서는 filter에서는 JWT를 해독하는 인증 + 해당 요청은 로그인 된 유저만 접근할 수 있다는 인가를 진행하고 MethodArgumentResolver
는 개발 편의를 위한 MemberAuth
의 객체를 만드는 역할만 하기 때문에 저는 인증/인가가 두 가지 스텝이라고 생각하고 있지 않습니다!
다른 부분에 대해서는 다 같이 얘기해보면 좋을 것 같아요 좋은 의견 감삼둥
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저는 Filter
를 활용하지 않는다면 Interceptor
가 좀 더 합리적이라고 생각됩니다. ArgumentResolver
의 역할은 인증/인가라기 보단 인증/인가된 대상을 메소드 인자로 할당하는 것이라고 생각합니다. 클로버가 적어주신 Filter
의 여러 단점(그 중에서도 전역 예외처리 불가)를 생각해보면 여러모로 굳이 도입할 이유가 없어보이긴 합니다.
전 Interceptor
로의 리팩토링에 찬성합니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
filter가 early return이 안된다는건 저의 허위사실 유포였습니다 사죄드립니다 리건 :cry ealry return으로 수정해뒀습니다,,,
if (token == null) { | ||
sendUnauthorizedResponse(response, "인증이 필요한 요청입니다."); | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
인증
, 요청
이라는 워딩보다는 로그인
등의 표현이 유저에게 가까울 것 같아요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
굳 바로 반영 고고링했심다
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
리비 코멘트 우선적으로 반영했습니당
주말인데도 빠른 코멘트 감동..
@RequiredArgsConstructor | ||
@Slf4j | ||
@Component | ||
public class JwtAuthFilter extends OncePerRequestFilter { | ||
|
||
private final ObjectMapper objectMapper; | ||
private final JwtTokenProvider tokenProvider; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interceptor로 변경하자는 의견이 아니라 ArgumentResolver에게 인가를 맡기자는거라면 반대입니당
인증되지 않은 사용자의 요청은 Handler까지 흘러들어와야 할 필요가 없다고 생각해요. 적어도 Interceptor를 통해 Handler가 불리기 이전에 blocking 되는게 리소스 낭비도 덜하고 보안적인 측면에서도 더 안전할 것 같습니다.
위의 이유로 MethodArguementResolver는 모든 메서드의 파라미터를 처리할 때 공통적으로 필요할 때 사용되는 기능이지 인증/인가를 위한 기능이라고 생각되지 않습니다. 🙇
if (token == null) { | ||
sendUnauthorizedResponse(response, "인증이 필요한 요청입니다."); | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
굳 바로 반영 고고링했심다
try { | ||
return Jwts.parserBuilder() | ||
.setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8)) | ||
.build() | ||
.parseClaimsJws(token) | ||
.getBody() | ||
.get(MEMBER_ID_KEY) | ||
.toString(); | ||
} catch (ExpiredJwtException exception) { | ||
throw new UnauthorizedException("이미 만료된 토큰입니다."); | ||
} catch (Exception exception) { | ||
throw new UnauthorizedException("유효하지 않은 토큰입니다."); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반영 완료했심다 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
클로버 고생 많으셨습니다!
제 생각에도 Filter
를 도입했을 때의 이점보다 단점이 더 많은 것 같습니다.
if-else
구문의 등장만으로 저희 레벨 1, 2를 완전 부정하는 것 같아서 꺼려지네요.
저는 Interceptor
로의 리팩토링을 제안해봅니다!
@RequiredArgsConstructor | ||
@Slf4j | ||
@Component | ||
public class JwtAuthFilter extends OncePerRequestFilter { | ||
|
||
private final ObjectMapper objectMapper; | ||
private final JwtTokenProvider tokenProvider; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저는 Filter
를 활용하지 않는다면 Interceptor
가 좀 더 합리적이라고 생각됩니다. ArgumentResolver
의 역할은 인증/인가라기 보단 인증/인가된 대상을 메소드 인자로 할당하는 것이라고 생각합니다. 클로버가 적어주신 Filter
의 여러 단점(그 중에서도 전역 예외처리 불가)를 생각해보면 여러모로 굳이 도입할 이유가 없어보이긴 합니다.
전 Interceptor
로의 리팩토링에 찬성합니다!
Test Results12 files 12 suites 4s ⏱️ Results for commit ef20383. ♻️ This comment has been updated with latest results. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
작성하신 auth filter 우선 운용하는걸로 하시죠!
백로그에 남겨두었습니다. 후에 리팩토링 토의 하면 좋을 것 같습니다 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filter에서 early return
이 가능하다면 굳이 사용하지 않을 이유도 없을 것 같네요.
고생하셨습니다 클로버!
* feat: UnauthorizedException 추가 * feat: Swagger에 Authorization 추가 * feat: Authorization Header 검증용 filter 구현 * feat: 로그인된 사요앚 정보 얻기 위한 ArgumentResolver 구현 * test: TravelPlanController 테스트에 accessToken 추가 * refactor: 필터에서 token이 없을 경우의 에러메시지 수정 * refactor: JwtTokenProvider 예외 발생 시 cause 포함되게 수정 * refactor: JwtAuthFilter else문 제거
* feat: UnauthorizedException 추가 * feat: Swagger에 Authorization 추가 * feat: Authorization Header 검증용 filter 구현 * feat: 로그인된 사요앚 정보 얻기 위한 ArgumentResolver 구현 * test: TravelPlanController 테스트에 accessToken 추가 * refactor: 필터에서 token이 없을 경우의 에러메시지 수정 * refactor: JwtTokenProvider 예외 발생 시 cause 포함되게 수정 * refactor: JwtAuthFilter else문 제거
✅ 작업 내용
🙈 참고 사항
filter는 return도 때릴 수가 없어서 if-else 구문이 생겼습니다. 여기서 개선점 좀 찾아보겠슴다. 있으면 제보 바람 22early return 되네요 허위사실 유포 죄송합니다 여러분