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

[Feature] - 인가 구현 #79

Merged
merged 9 commits into from
Jul 30, 2024
Merged

[Feature] - 인가 구현 #79

merged 9 commits into from
Jul 30, 2024

Conversation

eunjungL
Copy link

@eunjungL eunjungL commented Jul 21, 2024

✅ 작업 내용

  • Filter를 통한 Authorization Header 여부 검사 및 JWT 해독
  • ArgumentResolver를 사용해 현재 로그인한 사용자 조회

🙈 참고 사항

  • 인증이 필요한 곳이 필요 없는 곳보다 훨씬 많을 것이라 생각해 filter를 도입해봤는데 지금 상태에서 오히려 복잡해지기만 한건지 확신이 안서네요. 차라리 인터셉터로 구현하는게 나았을지 의견 부탁드립니다.
  • filter는 dispatcherServlet에 들어가기 이전에 동작하는거라 발생하는 에러에 대해 ControllerAdvice로 잡을 수가 없습니다. 이 부분에 대해서는 개선점을 좀 찾아보겠습니다. 있으면 제보 바람 😢
  • filter는 return도 때릴 수가 없어서 if-else 구문이 생겼습니다. 여기서 개선점 좀 찾아보겠슴다. 있으면 제보 바람 22 early return 되네요 허위사실 유포 죄송합니다 여러분

@eunjungL eunjungL added the BE label Jul 21, 2024
@eunjungL eunjungL added this to the sprint 2 milestone Jul 21, 2024
@eunjungL eunjungL self-assigned this Jul 21, 2024
Copy link

github-actions bot commented Jul 21, 2024

Unit Test Results

0 tests   0 ✔️  0s ⏱️
0 suites  0 💤
0 files    0

Results for commit f769c2e.

♻️ This comment has been updated with latest results.

Copy link

@Libienz Libienz left a comment

Choose a reason for hiding this comment

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

안녕하세요 클로버 🍀

주말인데 고생많으셨습니다.

인가 방식에 대한 것과 나머지 간단한 코멘트 남겨드렸어요
방식을 정하고 넘어가면 좋을 것 같아 우선은 RC 남겨드립니다.
회의가 필요할 수도 있을 것 같군요 🤔

ps. 인가를 구현하신 것으로 확인했는데 PR제목과 코드에서 사용되는 여러 용어 검토 부탁드립니다

Comment on lines 43 to 55
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("유효하지 않은 토큰입니다.");
}
Copy link

Choose a reason for hiding this comment

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

try catch 사용하는 만큼 stackTrace를 확인할 수 있게 cause를 예외 생성시에 추가시켜 주세용

Copy link
Author

Choose a reason for hiding this comment

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

반영 완료했심다 👍

Comment on lines +23 to +29
@RequiredArgsConstructor
@Slf4j
@Component
public class JwtAuthFilter extends OncePerRequestFilter {

private final ObjectMapper objectMapper;
private final JwtTokenProvider tokenProvider;
Copy link

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 될 때마다 인가하도록 처리하면 제가 말씀드린 방식의 구현이 됩니닷
인자가 붙어있는 컨트롤러 메서드에서만 인가가 이루어지도록 처리할 수 있쥬

클로버의 의견 들려주세요!

Copy link
Author

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는 모든 메서드의 파라미터를 처리할 때 공통적으로 필요할 때 사용되는 기능이지 인증/인가를 위한 기능이라고 생각되지 않습니다. 🙇

Copy link
Author

Choose a reason for hiding this comment

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

+) 추가로 화이트 리스트는 이후 더 늘어날 곳은 없어보입니다. 유지보수가 힘들 것 같지는 않아용!

Copy link

Choose a reason for hiding this comment

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

오 .. 몰랐던 시각이에요
클로버의 말 이해했고 충분히 합리적이라는 생각이 드네요.

다만 인터셉터 혹은 필터로 분리할 경우 인가과정이 두개의 스텝으로 진행되면서 한눈에 들어오지 않는 것도 사실 인 것 같아요.
그리고 리소스 낭비를 이야기 하셨는데 트랜잭션이 열리기 전에 요청이 반려된다면 리소스 낭비가 그렇게 심할지도 의문이긴 합니다.

저는 개인적으로 argumentResolver에서 한큐에 처리하고 싶다는 생각이기는 한데요, 제가 일반적인 방법을 모르고 있어서 저도 제 방식에 확신을 하지는 못합니다.

다 같이 얘기해보면 좋을 것 같아유!

Copy link
Author

Choose a reason for hiding this comment

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

다만 인터셉터 혹은 필터로 분리할 경우 인가과정이 두개의 스텝으로 진행되면서 한눈에 들어오지 않는 것도 사실 인 것 같아요.

요 부분에 대해서는 filter에서는 JWT를 해독하는 인증 + 해당 요청은 로그인 된 유저만 접근할 수 있다는 인가를 진행하고 MethodArgumentResolver는 개발 편의를 위한 MemberAuth의 객체를 만드는 역할만 하기 때문에 저는 인증/인가가 두 가지 스텝이라고 생각하고 있지 않습니다!

다른 부분에 대해서는 다 같이 얘기해보면 좋을 것 같아요 좋은 의견 감삼둥

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로의 리팩토링에 찬성합니다!

Copy link
Author

@eunjungL eunjungL Jul 22, 2024

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으로 수정해뒀습니다,,,

Comment on lines 48 to 50
if (token == null) {
sendUnauthorizedResponse(response, "인증이 필요한 요청입니다.");
} else {
Copy link

Choose a reason for hiding this comment

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

인증, 요청 이라는 워딩보다는 로그인등의 표현이 유저에게 가까울 것 같아요!

Copy link
Author

Choose a reason for hiding this comment

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

굳 바로 반영 고고링했심다

Copy link
Author

@eunjungL eunjungL left a comment

Choose a reason for hiding this comment

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

리비 코멘트 우선적으로 반영했습니당
주말인데도 빠른 코멘트 감동..

Comment on lines +23 to +29
@RequiredArgsConstructor
@Slf4j
@Component
public class JwtAuthFilter extends OncePerRequestFilter {

private final ObjectMapper objectMapper;
private final JwtTokenProvider tokenProvider;
Copy link
Author

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는 모든 메서드의 파라미터를 처리할 때 공통적으로 필요할 때 사용되는 기능이지 인증/인가를 위한 기능이라고 생각되지 않습니다. 🙇

Comment on lines 48 to 50
if (token == null) {
sendUnauthorizedResponse(response, "인증이 필요한 요청입니다.");
} else {
Copy link
Author

Choose a reason for hiding this comment

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

굳 바로 반영 고고링했심다

Comment on lines 43 to 55
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("유효하지 않은 토큰입니다.");
}
Copy link
Author

Choose a reason for hiding this comment

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

반영 완료했심다 👍

@eunjungL eunjungL requested a review from Libienz July 21, 2024 15:00
@eunjungL eunjungL changed the title [Feature] - 인증 구현 [Feature] - 인가 구현 Jul 21, 2024
Copy link

@hangillee hangillee left a 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로의 리팩토링을 제안해봅니다!

Comment on lines +23 to +29
@RequiredArgsConstructor
@Slf4j
@Component
public class JwtAuthFilter extends OncePerRequestFilter {

private final ObjectMapper objectMapper;
private final JwtTokenProvider tokenProvider;

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로의 리팩토링에 찬성합니다!

Copy link

github-actions bot commented Jul 22, 2024

Test Results

12 files  12 suites   4s ⏱️
33 tests 32 ✅ 1 💤 0 ❌
34 runs  33 ✅ 1 💤 0 ❌

Results for commit ef20383.

♻️ This comment has been updated with latest results.

@eunjungL eunjungL linked an issue Jul 24, 2024 that may be closed by this pull request
2 tasks
Copy link

@Libienz Libienz left a comment

Choose a reason for hiding this comment

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

작성하신 auth filter 우선 운용하는걸로 하시죠!

백로그에 남겨두었습니다. 후에 리팩토링 토의 하면 좋을 것 같습니다 👍

Copy link

@hangillee hangillee left a comment

Choose a reason for hiding this comment

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

Filter에서 early return이 가능하다면 굳이 사용하지 않을 이유도 없을 것 같네요.

고생하셨습니다 클로버!

@eunjungL eunjungL merged commit 06d7eb3 into develop/be Jul 30, 2024
3 checks passed
@eunjungL eunjungL deleted the feature/be/#69 branch July 30, 2024 04:59
eunjungL added a commit that referenced this pull request Jul 30, 2024
* feat: UnauthorizedException 추가

* feat: Swagger에 Authorization 추가

* feat: Authorization Header 검증용 filter 구현

* feat: 로그인된 사요앚 정보 얻기 위한 ArgumentResolver 구현

* test: TravelPlanController 테스트에 accessToken 추가

* refactor: 필터에서 token이 없을 경우의 에러메시지 수정

* refactor: JwtTokenProvider 예외 발생 시 cause 포함되게 수정

* refactor: JwtAuthFilter else문 제거
hangillee pushed a commit to hangillee/2024-touroot that referenced this pull request Aug 20, 2024
* feat: UnauthorizedException 추가

* feat: Swagger에 Authorization 추가

* feat: Authorization Header 검증용 filter 구현

* feat: 로그인된 사요앚 정보 얻기 위한 ArgumentResolver 구현

* test: TravelPlanController 테스트에 accessToken 추가

* refactor: 필터에서 token이 없을 경우의 에러메시지 수정

* refactor: JwtTokenProvider 예외 발생 시 cause 포함되게 수정

* refactor: JwtAuthFilter else문 제거
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

[Feature] - 인가 구현
3 participants