ํ ํ๋ก์ ํธ ๋ ํฌ์งํ ๋ฆฌ
- ๋ถ์ : Needle์ SNSํ์ง ๋ง๋ผ~
KP3C-backoffice-project
Redis ๋์
ํด๋ณด๊ธฐ #47, [Feature] Redis ๋์
ํ๊ธฐ #52
- ๋ฌธ์ ์ํฉ ๋ฐ ๊ตฌํ์ ๋์๋ ๋งํ ๊ด๋ จ ์ฌ๋ก ๊ธฐ๋ก
- ๊ฐ๋จํ ๊ฒ์๊ธ ์บ์ฑ
- RedisConfig ๋ฐ RedisUtils ์์ฑ
[Feature] ํ์ ๊ณ์ ์ฐจ๋จ/์ ๊ธ #64
1) User ์ํฐํฐ์ enabled
ํ๋ ์ถ๊ฐ
/* User.java */
@Column(columnDefinition = "char(1)")
private Boolean enabled; // ์ก์ธ์ค ๊ฐ๋ฅ
2) AuthenticationFailureHandler์์ ๋ก๊ทธ์ธ ์คํจ ์ฒ๋ฆฌ
3) AdminUserService.blockUser() ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ์ ์ ๋ฅผ ์ฐจ๋จ
4) @PreAuthorize()
๋ฅผ ์ฌ์ฉํด enabled=false์ธ ํ์์ ์ ๊ทผ ์ฐจ๋จ
@PreAuthorize("principal.enabled")
5) RedisUtils ์์ (๋ฐ์ดํฐ ํ์
์ถ๊ฐ(hash))
- ๊ธฐ์กด์๋ List ํ์
์ผ๋ก๋ง ๊ด๋ฆฌํ๋๋ฐ, ๊ตฌ์กฐ๋ก ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋๋ค๋ณด๋ refresh token๊ณผ access token์ ๋์์ ๊ด๋ฆฌํ ์ ์์๋ค. (ํ๋์ key์ value๊ฐ ๋ฎ์ด์ฐ์) ๋ฐ๋ผ์ ๊ตฌ์กฐ๋ก ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋๋ Hash ํ์
์ ์ถ๊ฐํ์ฌ refresh token๊ณผ access token ๋ ๊ฐ์ง ๋ชจ๋๋ฅผ ์ ์ฅํ ์ ์๋๋ก ํ๋ค.
- ๊ธฐ์กด์ ์๋ put()
๋ฉ์๋๋ฅผ ์ค๋ฒ๋ก๋ฉ ํ์๋ค. (get()
๋ฉ์๋์ delete()
๋ฉ์๋๋ ๊ฐ์ ๋ฐฉ์์ผ๋ก ์ค๋ฒ๋ก๋ฉ ํด์ฃผ์๋ค.)
public void put(String key, Object hashKey, Object value, Long expirationTime) {
String token = hashKey.toString();
redisTemplate.setHashKeySerializer(new StringRedisSerializer()); // key ๊ฐ ์ง๋ ฌํ
redisTemplate.setHashValueSerializer(new StringRedisSerializer()); // value ๊ฐ ์ง๋ ฌํ
redisTemplate.opsForHash().put(key, token, value); // hash type์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์ฅ
if(expirationTime != null) {
Duration timeout = Duration.ofSeconds(expirationTime);
redisTemplate.setHashKeySerializer(new StringRedisSerializer()); // key ๊ฐ ์ง๋ ฌํ
redisTemplate.expire(token, timeout); // token์ key ๊ฐ์ผ๋ก ํ์ฌ ์๋ฉธ ์๊ฐ ์ ์ฅ
}
}
6) ์ ์ฅ ๋ฐ์ดํฐ ํ์
์ถ๊ฐ๋ก ์ธํ ์ ์ฅ ๋ฐฉ์ ๋ณ๊ฒฝ(hash)
6-1. token์ด ์์ฑ๋๊ณ ์ ์ฅ๋ ๋
/* JwtUtil.java */
public TokenDto issueToken(String email, UserRoleEnum role) {
String accessToken = createAccessToken(email, role); // access token
redisUtils.put(email, "access_token", accessToken, ACCESS_TOKEN_TIME);
String refreshToken = createRefreshToken(email); // refresh token
redisUtils.put(email, "refresh_token", refreshToken, REFRESH_TOKEN_TIME);
// redisUtils.put(email, refreshToken, REFRESH_TOKEN_TIME); // <- ๊ธฐ์กด List ํํ ์ ์ฅ ๋ฐฉ์
return new TokenDto(accessToken, refreshToken);
}
6-2. token ์ ๋ณด๋ฅผ ์ฐพ๊ณ ์ญ์ ํ ๋
/* AdminUserService.java */
public void blockUser(Long userId, User admin) {
/* ํ์ ๊ถํ ํ์ธ ๋ฉ์๋ */
/* ์๋ต */
User findUser = findUser(userId);
findUser.setEnabled(false); // ํ์ ์ฐจ๋จ โ enable=false๋ก ์ ํ
// redis์์ access token ์ ๋ณด get
String accessToken = redisUtils.get(findUser.getEmail(), "access_token", String.class);
// redis์ access token ์ ๋ณด put - block์์ ๋ช
์
redisUtils.put(accessToken, "block", JwtUtil.ACCESS_TOKEN_TIME); // blacklist ์ ๋ฑ๋ก
redisUtils.delete(findUser.getEmail(), "refresh_token"); // refresh token ์ญ์
redisUtils.delete(findUser.getEmail(), "access_token"); // access token ์ญ์
}
[Feature] Username๊ณผ Email ๋ ๊ฐ์ง๋ก ๋ก๊ทธ์ธํ๊ธฐ #63
1) findByUsernameOrEmail ๋ฉ์๋ ์ถ๊ฐ
Optional<User> findByUsernameOrEmail(String username, String email);
2) findByUser() โ findByUserOrEmail()
@Override
public UserDetails loadUserByUsername(String usernameOrEmail) throws UsernameNotFoundException {
User user = userRepository.findByUsernameOrEmail(usernameOrEmail, usernameOrEmail)
.orElseThrow(() -> new UsernameNotFoundException("Not Found " + usernameOrEmail));
return new UserDetailsImpl(user);
}
โ ์์ฑํ์ง ๋ชปํ ๋ถ๋ถ์์ ์์ฌ์ด ์๊ฒจ ์ด์ด์ ํด๋ณด๊ธฐ๋ก ํ๋ค KP3C-project-refactor
๋ฑ ์ผ์ฃผ์ผ๋ง ๋ ์์์ผ๋ฉด ์ข๊ฒ ๋ค๊ณ ์๊ฐํ๋๋ฐ
ํ์ฌํผ ๋ค์ ํ๋ก์ ํธ ์ ๊น์ง ๋ชป ๋๋ด๋ฉด ๊ฐ๊ฐ ๋๋ ๊ฑธ๋ก...