728x90
1.회원가입, 로그인,로그아웃 엔드포인트
우선 로그인, 로그아웃은 Auth 엔드포인트로 묶고 회원가입은 Member 엔드포인트에 묶어서 제작하기로하였다.
@RestController
@RequiredArgsConstructor
@RequestMapping("/member")
@Tag(name = "맴버API", description = "/member")
public class MemberController {
@PostMapping("/register")
public void register(){
}
}
@RestController
@RequiredArgsConstructor
@RequestMapping("/auth")
@Tag(name = "인증API", description = "/auth")
public class AuthController {
@PostMapping("/login")
public void login(){
}
@PostMapping("/logout")
public void logout(){
}
}
2.SecurityConfig 설정
회원의 인증을 관리하는 엔드포인트를 제작해야하는만큼 보안과 관련된 설정들을 제작하였다.
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
// 인증 및 권한 설정
.authorizeHttpRequests(auth -> auth
.requestMatchers("/**").permitAll() // 다허용
.anyRequest().authenticated() // 나머지 모든 요청은 인증 필요
)
// CSRF 보호 (JWT 사용 시 비활성화)
.csrf(csrf -> csrf.disable())
// H2 Console을 위한 헤더 설정
.headers(headers -> headers
.frameOptions(frame -> frame.sameOrigin()));
return http.build();
}
// 비밀번호 암호화 설정
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
// AuthenticationManager 등록
@Bean
AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
}
2-1.인증,권한 설정
일단 지금까지 보안을 요구하는 엔드포인트를 만들지않았으므로 모든 엔드포인트에대해 인증없이 접근을 가능하게 설정하였다.
.authorizeHttpRequests(auth -> auth
.requestMatchers("/**").permitAll() // 다허용
.anyRequest().authenticated() // 나머지 모든 요청은 인증 필요
)
2-2.CSRF 보호
CSRF공격을 방어하기 위한 설정을 추가하였다.
추후 JWT로 사용할시 비활성화할예정이다.
.csrf(csrf -> csrf.disable())
2-4.H2 콘솔 설정
H2 콘솔에서 iframe을 사용할수있게 설정한다.
.headers(headers -> headers
.frameOptions(frame -> frame.sameOrigin()))
2-5.비밀번호 암호화 설정
BCryptPasswordEncoder로 사용자의 비밀번호를 암호화해서 DB에 저장하기위한 설정
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
2-6.AuthenticationManager 설정
Spring Security에서 사용자의 인증을 담당하는인터페이스인 AuthenticationManager 를 등록해준다.
// AuthenticationManager 등록
@Bean
AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
3.회원가입만들기
3-1.MemberRegisterDto
회원가입할때 받을데이터 DTO다.
유효성 검사를 위한 어노테이션들을 작성했다.
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class MemberRegisterDto {
@NotNull(message = "사용자 ID는 필수입니다.")
private String memberId;
@NotNull(message = "비밀번호는 필수입니다.")
@Size(min = 6, message = "비밀번호는 최소 6자 이상이어야 합니다.")
private String password;
@NotNull(message = "닉네임은 필수입니다.")
private String nickname;
@NotNull(message = "역할은 필수입니다.")
@Pattern(regexp = "CUSTOMER|SELLER|BOTH", message = "역할은 'CUSTOMER', 'SELLER', 'BOTH' 중 하나여야 합니다.")
private String role;
public Member.Role getRole() {
return Member.Role.valueOf(this.role);
}
}
3-2. Member Register 컨트롤러
MemberRegisterDto을 RequestBody으로 HTTP 요청의 본문에서JSON 데이터받아 자바 객체로 변환한다.
BindingResult는 유효성 검사결과를 담은 객체로 오류가있으면 처리해주는 로직을 작성해준다.
@PostMapping("/register")
public ResponseEntity<String> register(@RequestBody @Valid MemberRegisterDto memberRegisterDto, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
StringBuilder errorMessage = new StringBuilder();
for (ObjectError error : bindingResult.getAllErrors()) {
errorMessage.append(error.getDefaultMessage()).append("\n");
}
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorMessage.toString());
}
memberService.register(memberRegisterDto);
return ResponseEntity.status(HttpStatus.CREATED).body("회원가입 성공");
}
3-3.Register 서비스
서비스에서 passwordEncoder를 통해 비밀번호는 암호화처리를 하고 member에저장해준다.
그후 역할에 따라 CUSTOMER나 SELLER에 회원가입 로직을 처리해준다.
public void register(MemberRegisterDto memberRegisterDto) {
// 비밀번호 암호화
String encodedPassword = passwordEncoder.encode(memberRegisterDto.getPassword());
// 사용자 정보 저장
Member member = Member.builder()
.memberId(memberRegisterDto.getMemberId())
.password(encodedPassword)
.nickname(memberRegisterDto.getNickname())
.role(memberRegisterDto.getRole())
.build();
memberRepository.save(member);
if (member.getRole() == Member.Role.CUSTOMER) {
customerService.registerCustomer(member);
}
if (member.getRole() == Member.Role.SELLER) {
sellerService.registerSeller(member);
}
}
public class CustomerService {
private final CustomerRepository customerRepository;
public void registerCustomer(Member member){
Customer customer = new Customer();
customer.setMember(member);
customerRepository.save(customer);
}
}
public class SellerService {
private final SellerRepository sellerRepository;
public void registerSeller(Member member){
Seller seller = new Seller();
seller.setMember(member);
sellerRepository.save(seller);
}
}
4.회원가입 테스트
회원가입이 정상적으로 작동하는지 테스트해보자
curl -X 'POST' \
'http://localhost:8080/member/register' \
-H 'accept: */*' \
-H 'Content-Type: application/json' \
-d '{
"memberId": "test13131",
"password": "test13131",
"nickname": "테스트 닉네임123",
"role": "CUSTOMER"
}'
반환값 자체는 정상적으로 반환된것을 확인했으므로 h2에서 정상적으로 됬는지 확인하자
맴버 테이블을 조회했을때 비밀번호는 잘 암호화 된것을 확인할수있다.
Customer 테이블을 조회했을때 36번 아이디의 고객이 정상적으로 등록된것을 확인할수있다.
5.프론트엔드 폼제작
프론트엔드에서 폼을만들어서 정상적으로 POST로 회원가입이 되는지 테스트해보자
네트워크란에서 정상적으로 POST된것을 확인하였다.
방금 프론트에서 작성했던 맴버를 h2 데이터베이스에서 조회할수있었다.
728x90
'BackEnd > SpringBoot' 카테고리의 다른 글
[SpringBoot] JWT와 로그인,로그아웃 기능 제작 (0) | 2025.02.22 |
---|---|
[SpringBoot] 쇼핑몰 상품 조회기능 만들기 (0) | 2025.02.20 |
[SpringBoot] Test로 데이터 추가하기 경매장#7 (0) | 2024.11.05 |