1. DB MySQL 연결 & 환경 변수 처리
1) main/resources/application.properties 설정

2) main/resources/application-dev.properties 설정

3) main/resources/application-prod.properties 설정

4) .vscode/launch.json 설정
(1) .vscode 파일 안에 lauch.json 파일을 생성

(2) 아래 이미지처럼 환경변수 설정해주기


(3) 실행은 Run and Debug 아이콘 클릭해서 들어간 다음 위에 있는 실행 버튼을 클릭해서 실행해야한다.

5) build.gradle 파일 설정
mysql을 사용하기 때문에 mysql 의존성 추가

2. 회원가입 구현
User(entity), JoinRequest(dto), AuthController, AuthService, UserRepository, SecurityConfig, Role(enum), UserStatus(enum) 생성
1) User - entity
- 회원가입에 필요한 기본 요소를 필드로 정의.
- id, username, password, email, role, joinDate, lastLoginDate, status 설정.
- MySQL과 연결해야하기 때문에 @Entity 어노테이션을 사용.
- 혹시 몰라서 @Table 어노테이션을 사용해서 user 테이블과 연결. => @Table(name = "user")
- id는 데이터베이스 테이블에 설정한 것을 따르도록 설정 => @GeneratedValue(strategy = GenerationType.IDENTITY)
- @PrePersist와 @PreUpdate 어노테이션을 사용하여 설정. 가입시간/상태, 마지막 로그인 시간 메서드 정의.
2) JoinRequest - dto
- 회원가입 때 계층간 주고받아야할 dto를 따로 정의
- 사용자한테 입력받아야 하는 정보는 username, password, email이기 때문에 이 세가지 요소만 정의.
3) Role, UserStatus - enum
- Role: ROLE_USER, ROLE_ADMIN, ROLE_MANAGER 정의
- UserStatus: ACTIVE, INACTIVE, SUSPENDED, DELETED 정의
- enum으로 관리하여 재사용성과 유지보수에 용이하게 만들기
4) AuthController
- @RequestMapping 어노테이션 사용하여 기본 주소는 /api/v1/auth 로 설정. => @RequestMapping("/api/v1/auth")
- 회원가입 api는 Post형식으로 /signup uri로 설정.
- ResponseEntity<String> 타입으로 설정하고 매개변수로는 @RequestBody로 데이터 받기. 데이터는 JoinRequest dto 타입으로 받는다.
- 사용자로부터 받은 JoinRequest dto를 authService로 보내어 회원가입 시키고 반환값으로 userId를 받기.
- return 값으로 .status(HttpStatus.CREATED) 상태와 .body()에는 회원가입이 완료되었다는 문구와 userId 출력.
5) AuthService
- AuthController로 전달 받은 JoinRequest를 User 객체로 만들기. 객체로 만드는 방법은 .builder()사용.
- username, password, email, role, joinDate를 설정해주는데, passoword는 PasswordEncoder를 사용하여 비밀번호를 암호화하여 저장.
- return 값으로 userRepsitory를 통해 User 객체를 DB에 저장하고 getId() 메서드를 사용해 id를 가져와 AuthController에 반환.
6) UserRepository
- JpaReopsitory를 상속 받도록 설정. => public interface UserRepository extends JpaRepository<User, Long> { ... }
- JpaRepository를 상속받았기 때문에 기본으로 제공하는 메서드가 있어서 따로 설정할 게 없음.
7) SecurityConfig
- SecurityFilterChain으로 .csrf(), .sessionManagement(), .requestMatchers(), .anyRequest() 설정하고 @Bean 어노테이션 사용하여 Bean으로 등록
- anyRequest() 설정할 때, 테스트를 계속 해야하기 때문에 .permitAll()로 설정함.
- PasswordEncoder를 @Bean으로 등록하여 BCryptPasswordEncoder() 사용할 수 있도록 설정.
3. 기본 예외처리 기능 초기화 & 메시지 설정
- BaseException.java, ErrorCode.java, ErrorResponse.java, GlobalExceptionHandler.java 설정
- MessageProvider.java, messages.properties 설정
- chat gpt의 도움으로 설정함. 공부 필요.
1) BaseException
- 기본이 되는 예외처리. RuntimeException을 상속받음. 런타임중에 발생하는 예외를 처리함.
- 생성자 BaseException에 파라미터로 ErrorCode를 받음.
- BaseException 또는 CustomException 으로 생성한다고 함.
2) ErrorCode - enum
- enum으로 만들었고 아이디, 이메일 중복 체크하여 예외를 던질 때 사용된다.
- HttpStatus, code, message 필드 정의.
3) ErrorResponse
- code, message를 필드로 가지고 있다.
- 생성자로 ErrorCode를 매개변수로 받아서 code와 message에 ErrorCode의 code와 message를 가져와 저장.
- message는 MessageProvider를 통해 ErrorCode의 code를 message로 바꾸어 ErroResponse의 message 필드에 저장.
4) MessageProvider
- @Component 어노테이션을 사용
- MessageSource 객체 생성하여 messages.properties에 설정한 message를 가져옴.
- MessageProvider의 역할에 대해서 공부해야 함. 대충 흐름을 알겠는데 모르는 용어들이 많음.
5) messages.properties
- 회원가입 시 아이디, 이메일 중복되었다는 문구가 담긴 메시지 파일.
- 스프링에서 권장하는 방식이라고 함.
- 그리고 유지보수와 언어별 설정하기 용이하다고 함.
6) GlobalExceptionHandler
- 전역 예외처리 핸들러.
- BaseException 클래스에 보내는 예외처리.
7) application.properties에 메시지 설정 추가

4. 회원가입 예외처리 추가
1) AuthService
- if문을 사용하여 아이디 중복 체크와 이메일 중복 체크 기능 추가.
- 각각 username과 email이 중복되는지 체크. 중복되면 BaseException 예외 처리하는데, ErrorCode에 설정한 username중복, email 중복 에러코드로 throw 시키기.
2) UserRepository
- 아이디 중복 체크와 이메일 중복 체크는 boolean타임의 메서드롤 각각 생성.
- existsByUsername과 existsByEmail 메서드.