Home Spring, 이메일 인증 회원가입(3).
Post
Cancel

Spring, 이메일 인증 회원가입(3).

이메일_인증_회원가입(2)

  • 이번에 할것
    • Email 서비스 연동
    • 데이터 생성 API 만들기
    • 유저 권한 부여 API 만들기
    • POST MAN 문서 작성 틀 잡기
    • spring doc 설정


Email 서비스 연동

  • 회원가입시 이메일로 특정 키값을 보내고 해당 키를 인증하면 회원가입이 최종적으로 완료 되게 하는 서비스 구성
  • google-email 설정 부분만 참고하고 나머지 기능설정은 다르게 진행
    • application.properties 를 이용한 구성을 분리하여 직접 @Bean으로 등록
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Slf4j
@Configuration
@RequiredArgsConstructor
public class ProjectConfig {

  @Value("${spring.mail.service.username}")
  private String USER_NAME;

  @Value("${spring.mail.service.password}")
  private String PASSWORD;

  @Bean
  public JavaMailSender javaMailSender() {
    JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
    mailSender.setHost("smtp.gmail.com");
    mailSender.setPort(587);
    mailSender.setUsername(USER_NAME);
    mailSender.setPassword(PASSWORD);
    mailSender.getJavaMailProperties().put("mail.smtp.starttls.enable", "true");
    return mailSender;
  }

}


작업시 필요한 데이터를 생성하기 위한 엔드 포인트 생성

  • 유저 생성 API
  • 역할 생성 API
  • 권한 생성 API
  • 유저에게 역할을 부여하는 API
  • 역할에 권한들을 부여하는 API


데이터 생성 API

  • 단순 데이터 생성
    • insertUser(@RequestParam("size") int size)
      • 입력받은 사이즈만큼 User 데이터를 생성하고 생성된 User 리스트를 UserDto로 반환해서 리턴
    • insertRoles(@RequestBody RequestBodyContainer<List<String>> roleNameList)
      • 역할 이름을 문자열 형태의 리스트로 입력받고 생성된 Roles 리스트를 그대로 리턴
        • ToDo 추후 RolesDto를 반환하는것으로 수정
    • insertAuthority(@RequestBody List<AuthorityDto> authorityList)
      • 권한 목록을 입력받고 생성된 Authority 리스트를 그대로 리턴
        • ToDo 추후 AuthorityDto를 반환하는것으로 수정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping(path = "/api/v1/init-data")
public class InitDataController {

  private final CommonUtilService commonUtilService;

  @GetMapping(path = "/insert-users")
  public List<UserDto> insertUser(@RequestParam("size") int size) {
    List<User> userList = commonUtilService.insertRandomUser(size);
    log.info("init-data controller user list = {}", userList);
    return userList.stream().map(User::toDto).collect(Collectors.toList());
  }

  @PostMapping(path = "/insert-roles")
  public List<Roles> insertRoles(@RequestBody RequestBodyContainer<List<String>> roleNameList) {
    List<Roles> roles = commonUtilService.insertRole(roleNameList.getData());
    log.info("init-data controller roles list = {}", roles);
    return roles;
  }

  @PostMapping(path = "/insert-authorities")
  public List<Authority> insertAuthority(@RequestBody List<AuthorityDto> authorityList) {
    List<Authority> authorities = commonUtilService.insertAuthority(authorityList);
    log.info("init-data controller authorities = {}", authorities);
    return authorities;
  }


  @Getter
  @Setter
  @NoArgsConstructor
  @AllArgsConstructor
  public static class RequestBodyContainer<T> {
    private T data;
  }

}

유저 역할 부여 API

  • 해당 API 는 추후 서비스에 필요한 로직이라 따로 분리
    • givePermissionToAUser(@RequestBody UserDto.GivePermission givePermission)
      • 유저의 이메일과 권한의 이름을 입력받아 유저와 권한이 둘다 존재하면 유저에 역할 연결
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping(path = "/api/v1/user")
public class UserController {

  private final UserService userService;

  @PostMapping(path = "/give-permission")
  public ResponseEntity<UserDto> givePermissionToAUser(@RequestBody UserDto.GivePermission givePermission) {
    UserDto userDto = userService.givePermissionToAUser(givePermission);
    return new ResponseEntity<>(userDto, HttpStatus.OK);
  }

}

  • givePermissionToAUser() 구현체
    • User를 직접 반환 하려고 하면 no-session에러 발생 서비스단에서 리턴할 때에는 Dto로 변환하여 넘겨주자!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Override
public UserDto givePermissionToAUser(UserDto.GivePermission givePermission) {

  String userEmail = givePermission.getUserEmail();
  String roleName = givePermission.getRoleName();

  Optional<User> findUser = userRepository.findUserByUserEmail(userEmail);
  Optional<Roles> findRoles = rolesRepository.findRolesByRoleName(roleName);

  if (findUser.isPresent() && findRoles.isPresent()) {
    User user = findUser.get();
    Roles role = findRoles.get();
    user.setRoles(role);
    User result = userRepository.save(user);
    log.info("result = {}", result);
    return result.toDto();
  } else {
    return null;    //  ToDO 예외 처리 부분을 구체화 한다.
  }

}


POST MAN

  • 문서 구성
    • ToDO : happy, sad 케이스에 대한 폴더를 구분하여 문서화한다.

post_man


spring docs 설정

  • implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2' 해당 의존성 추가

  • 스프링 시큐리티를 활성화했음으로 spring docs에서 지원하는 리소스를 permitAll()해야함. 추가적으로 ignoreing()에도 추가
    • ToDO : swagger를 통해 API에 디테일한 설정을 추가해보자
  • SecurityConfig 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@Slf4j
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class WebSecurityConfig {

  private final CustomAuthenticationProvider customAuthenticationProvider;

  private static final String[] AUTH_WHITELIST = {
    "/api/**", "/swagger-ui/**", "/api-docs", "/swagger-ui-custom.html",
    "/v3/api-docs/**", "/api-docs/**", "/swagger-ui.html"
  };

  @Bean
  public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
    http
      .cors(AbstractHttpConfigurer::disable)
      .csrf(AbstractHttpConfigurer::disable)
      .authenticationProvider(customAuthenticationProvider)
      .authorizeHttpRequests(
        (requests) -> requests
          .requestMatchers(AUTH_WHITELIST).permitAll()
          .requestMatchers("/api/v*/**").permitAll()
          .anyRequest().permitAll()
      )
      .formLogin(withDefaults())
      .httpBasic(withDefaults());
    return http.build();
  }

  @Bean
  public WebSecurityCustomizer webSecurityCustomizer() {
    return (web) -> web.ignoring().requestMatchers(AUTH_WHITELIST);
  }

}

swagger_ui

  • 다음에 할것
    • 역할_권한 중간 테이블에 데이터 넣는 API추가
    • 토큰 인증 화면 구성(사용자에게 보내지는 메일을 꾸며주는 템플릿)
    • email-token관련 Entity추가 및 security 인증 로직 수정
This post is licensed under CC BY 4.0 by the author.