RestApi ๋งŒ๋“ค๊ธฐ - ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ์ ์šฉํ•˜๊ธฐ (12)

๋ฐ˜์‘ํ˜•

์›๋ž˜๋Š” ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•˜๊ณ  ํ•˜๋ ค๋‹ค๊ฐ€ 
๋„ˆ๋ฌด ์˜ค๋ž˜ ๊ฑธ๋ฆด ๊ฒƒ ๊ฐ™์•„ ์ƒ๋žตํ•˜๊ณ  ์ ์šฉํ•˜๋Š”๊ฒƒ๋ถ€ํ„ฐ ์ง„ํ–‰ํ•˜๋ ค๊ณ  ํ•œ๋‹ค.
์•„๋ฌดํŠผ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋ฅผ ์ ์šฉํ•˜๋Š” ์ด์œ ๋Š”
๊ฒŒ์‹œ๊ธ€์„ ๋งŒ๋“  ์œ ์ €๋งŒ ์ˆ˜์ •์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์ ์šฉํ•˜๋Š”๊ฑธ๋กœ ์•Œ๊ณ  ์žˆ๋‹ค.
์•„๋ฌดํŠผ... ์ ์šฉํ•ด๋ณด์ž.

 <dependency>
      <groupId>org.springframework.security.oauth.boot</groupId>
      <artifactId>spring-security-oauth2-autoconfigure</artifactId>
      <version>2.1.10.RELEASE</version>
</dependency>

์ด๊ฒƒ์„ ์ถ”๊ฐ€ํ•ด์ค˜์•ผ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
(์ด๊ธ€์€ ๋ฐฑ๊ธฐ์„ ๋‹˜ ๊ฐ•์˜๋ฅผ ๋ณด๊ณ  ์ž‘์„ฑํ•œ ๊ธ€์ด๊ธฐ๋•Œ๋ฌธ์— start.security๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.)
์ƒ๊ฐํ•ด๋ณด๋‹ˆ vo๋ฅผ ๋งŒ๋“ค์ง€ ์•Š์•˜๋‹ค.

@Getter @Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Account {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Integer id;
  private String username;
  private String password;
  
  @ElementCollection(fetch = FetchType.EAGER)
  @Enumerated(EnumType.STRING)
  private Set<AccountRole> roles;
}


์ด์ œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด์ž.

@SpringBootTest
@Import(RestDocsConfiguration.class)
@ActiveProfiles("test")
class AccountServiceTest {

  @Autowired
  private AccountService accountService;
  @Test
  void loadUser() {
    String username = "klom";
    String password = "1234";
    Account account = Account.builder()
        .username(username)
        .password(password)
        .roles(Set.of(AccountRole.ADMIN, AccountRole.USER))
        .build();
    UserDetails userDetails = accountService.loadUserByUsername(username);
    assertThat(userDetails.getPassword()).isEqualTo(password);
  }
}

๊ฐ„๋žตํžˆ ์„ค๋ช…ํ•˜๋ฉด account์—์„œ ๋ฐ›์€ ์ •๋ณด๋ž‘ accountService์—์„œ ๊ตฌํ•œ ํŒจ์Šค์›Œ๋“œ๊ฐ€ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋‹ค.
๋ฌผ๋ก  ์ด๊ฒƒ์„ ์‹คํ–‰ํ•ด๋ดค์ž ์˜๋ฏธ๊ฐ€ ์—†๋‹ค.
1. account๋Š” db์— ์ €์žฅํ•˜์ง€ ์•Š์•˜๋‹ค.
2. accountService๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•˜๋‹ค.
1๋ฒˆ ๋ถ€ํ„ฐ ์ ์šฉํ•ด๋ณด์ž.
์ ์šฉ๋’ค ์‹คํ–‰ํ•ด๋ณด๋‹ˆ.

nullPointExeption์ด ๋ฐœ์ƒํ–ˆ๋‹ค.
๊ทธ๋Ÿฌ๋ฉด userService์„ ์ˆ˜์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

@Service
public class AccountService implements UserDetailsService {

  private final AccountRepository accountRepository;

  public AccountService(
      AccountRepository accountRepository) {
    this.accountRepository = accountRepository;
  }

  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    Optional<Account> optAccount = accountRepository.findByUsername(username);
    Account account = optAccount
        .orElseThrow(() -> new UsernameNotFoundException("์œ ์ € ์ •๋ณด๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."));
    return new User(account.getUsername(), account.getPassword(), authorities(account.getRoles()));
  }

  private Collection<? extends GrantedAuthority> authorities(Set<AccountRole> roles) {
    return roles.stream().map(r -> new SimpleGrantedAuthority("_ROLE"+r.name())).collect(Collectors.toSet());
  }
}

๊ทธ๋ฆฌ๊ณ  ์‹คํ–‰์„ ํ•ด๋ณด๋ฉด...

๋‹คํ–‰ํžˆ ์„ฑ๊ณตํ–ˆ๋‹ค๋Š”๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
์ƒ๊ฐํ•ด๋ณด๋‹ˆ ํ•œ๊ฐ€์ง€ ์˜ˆ์™ธ๋ฅผ ๋นผ๋จน์—ˆ๋‹ค.
๋ฐ”๋กœ ์—†๋Š” ์‚ฌ์šฉ์ž๋ฅผ ์ž…๋ ฅํ–ˆ์„ ๊ฒฝ์šฐ๋Š” ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์•ผํ• ๊นŒ?

@Test
  void loadEmptyUser() {
    assertThrows(
        UsernameNotFoundException.class,
        () -> {
          String username = "klomlly";
          accountService.loadUserByUsername(username);
        }
    );
  }

์ด๋ ‡๊ฒŒ ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋ฉด๋œ๋‹ค.
์ด ๊ธฐ๋Šฅ์€ junit5์— ๋“ค์–ด์˜จ ๊ธฐ๋Šฅ์œผ๋กœ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ํ• ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.
์ด๋ ‡๊ฒŒ ์‹คํ–‰ํ•˜๋ฉด ์„ฑ๊ณตํ•œ๋‹ค.
๊ทธ๋Ÿฐ๋ฐ ๊ณผ์—ฐ ์ด ์ฝ”๋“œ๊ฐ€ ์„ฑ๊ณตํ–ˆ๋‹ค๊ณ  ์–ด๋–ป๊ฒŒ ์žฅ๋‹ดํ•  ์ˆ˜ ์žˆ์„๊นŒ?
๊ทธ๋ž˜์„œ db์— ์กด์žฌํ•˜๋Š” ์œ ์ €๋ฅผ ์ž…๋ ฅํ–ˆ์„ ๊ฒฝ์šฐ ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

@Test
  void loadEmptyUser() {
    String username = "klom";
    String password = "1234";
    Account account = Account.builder()
        .username(username)
        .password(password)
        .roles(Set.of(AccountRole.ADMIN, AccountRole.USER))
        .build();
    accountRepository.save(account);
    assertThrows(
        UsernameNotFoundException.class,
        () -> {
//          String username = "klomlly";
          accountService.loadUserByUsername(username);
        }
    );
  }

๋Œ€์ถฉ ์ฝ”๋“œ๋Š” ์ด๋ ‡๊ฒŒ ์ˆ˜์ •ํ•˜์˜€๋‹ค.
๊ฒฐ๊ณผ๋Š”

์™œ ์˜ˆ์™ธ์ฝ”๋“œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๊ณ  ํ–ˆ๋Š”๋ฐ, ์–ด์งธ์„œ ์ •์ƒ์ธ ์ฝ”๋“œ๊ฐ€ ๋“ค์–ด์™”๋ƒ๊ณ  ๋งํ•˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

... 

๋Œ“๊ธ€

Designed by JB FACTORY