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

Refactor #81 jwt role 추가 #81

Open
wants to merge 12 commits into
base: develop
Choose a base branch
from
Open

Conversation

hyxklee
Copy link
Member

@hyxklee hyxklee commented Nov 28, 2024

PR 내용

  • 스프링 시큐리티에서 권한검사를 하기 때문에 권한을 기존에는 유저 디비에서 조회한 사용자 정보를 바탕으로 검사를 진행했으나, 이가 비효율적이라 생각해 토큰에 역할을 담는 것으로 수정

PR 세부사항

  • 엑세스 토큰에 사용자 역할 담는 것으로 수정
  • 레디스 키를 이메일에서 userId로 수정. 이에 따라 리프레시 요청시 이메일을 주지 않아도 됨
  • 매번 요청시 디비에서 조회하지 않기 때문의 약간의 성능 향상 (평균 65ms -> 55ms 정도로 약 10ms의 성능 향상)
  • 해당 성능 향상은 모든 요청에 한하기 때문에 전반적인 응답속도 성능 향상을 만들 수 있음

관련 스크린샷

  • 수정전
image
  • 수정후
image

주의사항

  • 직접 요청 시간을 확인한 1차원 적인 임시 테스트이긴 하나 확실한 응답속도 향상이 있었음

체크 리스트

  • 리뷰어 설정
  • Assignee 설정
  • Label 설정
  • 제목 양식 맞췄나요? (ex. #0 Feat: 기능 추가)
  • 변경 사항에 대한 테스트

@hyxklee hyxklee self-assigned this Nov 28, 2024
@hyxklee hyxklee changed the title Refactor #80 jwt role 추가 Refactor #81 jwt role 추가 Nov 28, 2024
Copy link
Member

@huncozyboy huncozyboy left a comment

Choose a reason for hiding this comment

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

고생하셨습니다 !


log.info("RefreshToken 발급 완료: {}", dto.email());
log.info("RefreshToken 발급 완료: {}", token);
Copy link
Member

Choose a reason for hiding this comment

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

RefreshToken이 발급되는 로직을 확인하기 위해 log를 사용하신걸로 생각했습니다.
토큰 값과같이 민감한 정보는 출력되지 않도록하고 token.substring(0, 10) 이런식으로 일부만 확인하는건 어떨까요 ?

Copy link
Member Author

Choose a reason for hiding this comment

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

개발상 용이하게 확인 목적으로 로그를 찍어놨습니당 외부로 노출되는 부분이 아니고, 현재 개발 상태니까 별도의 로직을 넣기보단 그냥 두는 것은 어떨까요??

Comment on lines +31 to +33
redisTemplate.opsForHash().put(key, "token", refreshToken);
redisTemplate.opsForHash().put(key, "role", role.toString());
redisTemplate.opsForHash().put(key, "email", email);
Copy link
Member

Choose a reason for hiding this comment

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

Hash 타입을 사용해서 여러개 필드를 그룹화해서 관리한 것이 좋아보입니다

Comment on lines +61 to +63
return Optional.ofNullable(roleValue)
.map(Role::valueOf)
.orElseThrow(RoleNotFoundException::new);
Copy link
Member

Choose a reason for hiding this comment

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

두개의 예외처리 발생시 RoleNotFoundException로 한번에 처리해주는 것도 좋지만,
null인 경우와 잘못된 Role 값이 저장된 경우의 예외처리를 나눠서 서비스단에서 처리해주는 방식은 어떨까요 ?

Copy link
Member Author

Choose a reason for hiding this comment

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

유저의 역할이 저장되기 때문에 레디스에 저장될 때 잘못된 값이 저장될 일이 없다고 생각합니다.
이전 로직에서 Role에 대한 검증은 이루어진 후에 저장이 된다고 생각해요!
그렇다면 조회의 책임을 지는 메서드에서 잘못된 값을 검증할 필요는 없지 않을까요?? 어떻게 생각하시는지 궁금합니다!

Copy link
Member

Choose a reason for hiding this comment

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

넵 이중으로 검증을 해줄 필요는 없으니까 해당 방식으로 간결하게 구현하는게 좋을거같습니다 !

public void set(String email, String refreshToken) {
String key = getKey(email);
redisTemplate.opsForValue().set(key, refreshToken, expirationTime, TimeUnit.MILLISECONDS);
public void set(long userId, String refreshToken, Role role, String email) {
Copy link
Member

@huncozyboy huncozyboy Nov 28, 2024

Choose a reason for hiding this comment

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

set 메서드가 expirationTime, email, role, refreshToken 등의 여러 역할을 한번에 처리해주고 있는데
setRefreshToken, setUserMetadata, setExpiration 이런식으로 분리를 해주는게
유지보수 측면에서 좋을거같다는 생각이 있습니다

Copy link
Member Author

Choose a reason for hiding this comment

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

메서드로 분리해두는게 확장성이 좋을 것 같아요!
수정하겠습니당

Copy link
Collaborator

@jj0526 jj0526 left a comment

Choose a reason for hiding this comment

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

수고하셨습니다!

String accessToken = jwtProvider.createAccessToken(id, email);
String refreshToken = jwtProvider.createRefreshToken(id);
public JwtDto create(Long userId, String email, Role role){
String accessToken = jwtProvider.createAccessToken(userId, email, role);
Copy link
Collaborator

Choose a reason for hiding this comment

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

role까지 추가한거 확인했습니다!

String key = getKey(userId);

if (Boolean.TRUE.equals(redisTemplate.hasKey(key))) {
redisTemplate.opsForHash().put(key, "role", role);
Copy link
Collaborator

Choose a reason for hiding this comment

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

"role"로 겹치는데 JwtProvider의 private static final String ROLE_CLAIM = "role";처럼 상수화 해주시면 좋을거같습니다!

Copy link
Member Author

Choose a reason for hiding this comment

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

상수처리를 깜빡했네요! 수정하겠습니다

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants