๐ŸŒต WIL 10์ฃผ์ฐจ

temprmnยท2023๋…„ 7์›” 24์ผ
0
post-thumbnail

ํŒ€ ํ”„๋กœ์ ํŠธ ๋ ˆํฌ์ง€ํ† ๋ฆฌ

์ผ์ฃผ์ผ ๊ฐ„์˜ Pull Request

  1. Admin(๊ด€๋ฆฌ์ž) ๊ธฐ๋Šฅ
  1. Redis๋ฅผ ํ™œ์šฉํ•œ token ๊ด€๋ฆฌ
  • 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 ์‚ญ์ œ
     }
  1. ๊ทธ ์™ธ
  • [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);
    }
  1. ์™„์„ฑํ•˜์ง€ ๋ชปํ•ด์„œ ์•„์‰ฌ์› ๋˜ ์ด์Šˆ

โ†’ ์™„์„ฑํ•˜์ง€ ๋ชปํ•œ ๋ถ€๋ถ„์—์„œ ์š•์‹ฌ์ด ์ƒ๊ฒจ ์ด์–ด์„œ ํ•ด๋ณด๊ธฐ๋กœ ํ–ˆ๋‹ค KP3C-project-refactor

๋”ฑ ์ผ์ฃผ์ผ๋งŒ ๋” ์žˆ์—ˆ์œผ๋ฉด ์ข‹๊ฒ ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋Š”๋ฐ
ํ•˜์—ฌํŠผ ๋‹ค์Œ ํ”„๋กœ์ ํŠธ ์ „๊นŒ์ง€ ๋ชป ๋๋‚ด๋ฉด ๊ฐœ๊ฐ€ ๋˜๋Š” ๊ฑธ๋กœ...

profile
`ISFJ` T 49% F 51% /

0๊ฐœ์˜ ๋Œ“๊ธ€