-
Notifications
You must be signed in to change notification settings - Fork 0
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
The head ref may contain hidden characters: "Refactor/#79/jwt-role-\uCD94\uAC00"
Changes from all commits
8dafe54
1ac79fe
3c3e669
de98862
d7715df
44fa101
c62d3d1
e031f1d
f3c68ed
4b26032
58b112b
3dba93d
1607df9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package leets.weeth.domain.user.application.exception; | ||
|
||
import leets.weeth.global.common.exception.BusinessLogicException; | ||
|
||
public class EmailNotFoundException extends BusinessLogicException { | ||
public EmailNotFoundException() { | ||
super(404, "Redis에 저장된 email이 없습니다."); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package leets.weeth.domain.user.application.exception; | ||
|
||
import leets.weeth.global.common.exception.BusinessLogicException; | ||
|
||
public class RoleNotFoundException extends BusinessLogicException { | ||
public RoleNotFoundException() { | ||
super(404, "Redis에 저장된 role이 없습니다."); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
|
||
import jakarta.servlet.http.HttpServletRequest; | ||
import jakarta.servlet.http.HttpServletResponse; | ||
import leets.weeth.domain.user.domain.entity.enums.Role; | ||
import leets.weeth.global.auth.jwt.application.dto.JwtDto; | ||
import leets.weeth.global.auth.jwt.service.JwtRedisService; | ||
import leets.weeth.global.auth.jwt.service.JwtProvider; | ||
|
@@ -20,11 +21,11 @@ public class JwtManageUseCase { | |
private final JwtRedisService jwtRedisService; | ||
|
||
// 토큰 발급 | ||
public JwtDto create(Long id, String email){ | ||
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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. role까지 추가한거 확인했습니다! |
||
String refreshToken = jwtProvider.createRefreshToken(userId); | ||
|
||
updateToken(email, refreshToken); | ||
updateToken(userId, refreshToken, role, email); | ||
|
||
return new JwtDto(accessToken, refreshToken); | ||
} | ||
|
@@ -35,23 +36,26 @@ public void sendToken(JwtDto dto, HttpServletResponse response) throws IOExcepti | |
} | ||
|
||
// 토큰 재발급 | ||
public JwtDto reIssueToken(String email, HttpServletRequest request){ | ||
public JwtDto reIssueToken(HttpServletRequest request){ | ||
String requestToken = jwtService.extractRefreshToken(request); | ||
jwtProvider.validate(requestToken); | ||
|
||
Long userId = jwtService.extractId(requestToken).get(); | ||
|
||
jwtRedisService.validateRefreshToken(email, requestToken); | ||
jwtRedisService.validateRefreshToken(userId, requestToken); | ||
|
||
JwtDto token = create(userId, email); | ||
jwtRedisService.set(email, token.refreshToken()); | ||
Role role = jwtRedisService.getRole(userId); | ||
String email = jwtRedisService.getEmail(userId); | ||
|
||
JwtDto token = create(userId, email, role); | ||
jwtRedisService.set(userId, token.refreshToken(), role, email); | ||
|
||
return token; | ||
} | ||
|
||
// 리프레시 토큰 업데이트 | ||
private void updateToken(String email, String refreshToken){ | ||
jwtRedisService.set(email, refreshToken); | ||
private void updateToken(long userId, String refreshToken, Role role, String email){ | ||
jwtRedisService.set(userId, refreshToken, role, email); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,8 @@ | ||
package leets.weeth.global.auth.jwt.service; | ||
|
||
import leets.weeth.domain.user.application.exception.EmailNotFoundException; | ||
import leets.weeth.domain.user.application.exception.RoleNotFoundException; | ||
import leets.weeth.domain.user.domain.entity.enums.Role; | ||
import leets.weeth.global.auth.jwt.exception.InvalidTokenException; | ||
import leets.weeth.global.auth.jwt.exception.RedisTokenNotFoundException; | ||
import lombok.RequiredArgsConstructor; | ||
|
@@ -20,34 +23,68 @@ public class JwtRedisService { | |
private Long expirationTime; | ||
|
||
private static final String PREFIX = "refreshToken:"; | ||
private static final String TOKEN = "token"; | ||
private static final String ROLE = "role"; | ||
private static final String EMAIL = "email"; | ||
|
||
private final RedisTemplate<String, String> redisTemplate; | ||
|
||
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) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. set 메서드가 expirationTime, email, role, refreshToken 등의 여러 역할을 한번에 처리해주고 있는데 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 메서드로 분리해두는게 확장성이 좋을 것 같아요! |
||
String key = getKey(userId); | ||
put(key, TOKEN, refreshToken); | ||
put(key, ROLE, role.toString()); | ||
put(key, EMAIL, email); | ||
redisTemplate.expire(key, expirationTime, TimeUnit.MINUTES); | ||
log.info("Refresh Token 저장/업데이트: {}", key); | ||
} | ||
|
||
public void delete(String email) { | ||
String key = getKey(email); | ||
public void delete(Long userId) { | ||
String key = getKey(userId); | ||
redisTemplate.delete(key); | ||
} | ||
|
||
public void validateRefreshToken(String email, String requestToken) { | ||
if (!find(email).equals(requestToken)) { | ||
public void validateRefreshToken(long userId, String requestToken) { | ||
if (!find(userId).equals(requestToken)) { | ||
throw new InvalidTokenException(); | ||
} | ||
} | ||
|
||
private String find(String email) { | ||
String key = getKey(email); | ||
return Optional.ofNullable(redisTemplate.opsForValue().get(key)) | ||
public String getEmail(long userId) { | ||
String key = getKey(userId); | ||
String roleValue = (String) redisTemplate.opsForHash().get(key, "email"); | ||
|
||
return Optional.ofNullable(roleValue) | ||
.orElseThrow(EmailNotFoundException::new); | ||
} | ||
|
||
public Role getRole(long userId) { | ||
String key = getKey(userId); | ||
String roleValue = (String) redisTemplate.opsForHash().get(key, "role"); | ||
|
||
return Optional.ofNullable(roleValue) | ||
.map(Role::valueOf) | ||
.orElseThrow(RoleNotFoundException::new); | ||
Comment on lines
+64
to
+66
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 두개의 예외처리 발생시 RoleNotFoundException로 한번에 처리해주는 것도 좋지만, There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. 넵 이중으로 검증을 해줄 필요는 없으니까 해당 방식으로 간결하게 구현하는게 좋을거같습니다 ! |
||
} | ||
|
||
public void updateRole(long userId, String role) { | ||
String key = getKey(userId); | ||
|
||
if (Boolean.TRUE.equals(redisTemplate.hasKey(key))) { | ||
redisTemplate.opsForHash().put(key, "role", role); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "role"로 겹치는데 JwtProvider의 private static final String ROLE_CLAIM = "role";처럼 상수화 해주시면 좋을거같습니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 상수처리를 깜빡했네요! 수정하겠습니다 |
||
} | ||
} | ||
|
||
private String find(long userId) { | ||
String key = getKey(userId); | ||
return Optional.ofNullable((String) redisTemplate.opsForHash().get(key, "token")) | ||
.orElseThrow(RedisTokenNotFoundException::new); | ||
} | ||
|
||
private String getKey(String email){ | ||
return PREFIX + email; | ||
private String getKey(long userId) { | ||
return PREFIX + userId; | ||
} | ||
|
||
private void put(String key, String hashKey, Object value) { | ||
redisTemplate.opsForHash().put(key, hashKey, value); | ||
} | ||
} |
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.
RefreshToken이 발급되는 로직을 확인하기 위해 log를 사용하신걸로 생각했습니다.
토큰 값과같이 민감한 정보는 출력되지 않도록하고 token.substring(0, 10) 이런식으로 일부만 확인하는건 어떨까요 ?
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.
개발상 용이하게 확인 목적으로 로그를 찍어놨습니당 외부로 노출되는 부분이 아니고, 현재 개발 상태니까 별도의 로직을 넣기보단 그냥 두는 것은 어떨까요??