diff --git a/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/common/config/security/BCryptPasswordConfig.java b/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/common/config/security/BCryptPasswordConfig.java new file mode 100644 index 0000000..75b1727 --- /dev/null +++ b/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/common/config/security/BCryptPasswordConfig.java @@ -0,0 +1,16 @@ +package com.example.SecondSeminar.common.config.security; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +public class BCryptPasswordConfig { + private static final int STRENGTH = 10; + + @Bean + public PasswordEncoder bCryptPasswordEncoder() { + return new BCryptPasswordEncoder(STRENGTH); + } +} diff --git a/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/member/application/AuthMemberService.java b/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/member/application/AuthMemberService.java new file mode 100644 index 0000000..ffa2046 --- /dev/null +++ b/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/member/application/AuthMemberService.java @@ -0,0 +1,39 @@ +package com.example.SecondSeminar.member.application; + +import com.example.SecondSeminar.common.exception.BaseCustomException; +import com.example.SecondSeminar.member.domain.AuthMember; +import com.example.SecondSeminar.member.domain.AuthMemberJpaRepository; +import com.example.SecondSeminar.member.dto.request.AuthMemberRequest; +import com.example.SecondSeminar.member.exception.MemberExceptionType; +import lombok.RequiredArgsConstructor; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Service +public class AuthMemberService { + + private final AuthMemberJpaRepository authMemberJpaRepository; + private final PasswordEncoder passwordEncoder; + + @Transactional + public String create(AuthMemberRequest request) { + AuthMember authMember = AuthMember.builder() + .nickname(request.nickname()) + .password(passwordEncoder.encode(request.password())) + .build(); + authMemberJpaRepository.save(authMember); + + return authMember.getId().toString(); + } + + public void signIn(AuthMemberRequest request) { + AuthMember serviceMember = authMemberJpaRepository.findByNickname(request.nickname()) + .orElseThrow(() -> new BaseCustomException(MemberExceptionType.NOT_FOUND_MEMBER)); + if (!passwordEncoder.matches(request.password(), serviceMember.getPassword())) { + throw new BaseCustomException(MemberExceptionType.INCORRECT_PASSWORD); + } + } + +} diff --git a/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/member/domain/AuthMember.java b/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/member/domain/AuthMember.java new file mode 100644 index 0000000..56a6069 --- /dev/null +++ b/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/member/domain/AuthMember.java @@ -0,0 +1,29 @@ +package com.example.SecondSeminar.member.domain; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Entity +public class AuthMember { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String nickname; + private String password; + + @Builder + public AuthMember(String nickname, String password) { + this.nickname = nickname; + this.password = password; + } +} diff --git a/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/member/domain/AuthMemberJpaRepository.java b/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/member/domain/AuthMemberJpaRepository.java new file mode 100644 index 0000000..8777884 --- /dev/null +++ b/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/member/domain/AuthMemberJpaRepository.java @@ -0,0 +1,8 @@ +package com.example.SecondSeminar.member.domain; + +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface AuthMemberJpaRepository extends JpaRepository<AuthMember, Long> { + Optional<AuthMember> findByNickname(String nickname); +} diff --git a/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/member/dto/request/AuthMemberRequest.java b/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/member/dto/request/AuthMemberRequest.java new file mode 100644 index 0000000..9928c35 --- /dev/null +++ b/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/member/dto/request/AuthMemberRequest.java @@ -0,0 +1,7 @@ +package com.example.SecondSeminar.member.dto.request; + +public record AuthMemberRequest( + String nickname, + String password +) { +} diff --git a/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/member/exception/MemberExceptionType.java b/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/member/exception/MemberExceptionType.java index 891c31d..7e32dd6 100644 --- a/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/member/exception/MemberExceptionType.java +++ b/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/member/exception/MemberExceptionType.java @@ -6,7 +6,8 @@ @RequiredArgsConstructor public enum MemberExceptionType implements ExceptionType { - NOT_FOUND_MEMBER(HttpStatus.NOT_FOUND, "존재하지 않는 멤버입니다."); + NOT_FOUND_MEMBER(HttpStatus.NOT_FOUND, "존재하지 않는 멤버입니다."), + INCORRECT_PASSWORD(HttpStatus.UNAUTHORIZED, "비밀번호가 올바르지 않습니다."); private final HttpStatus httpStatus; private final String message; diff --git a/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/member/presentation/AuthMemberController.java b/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/member/presentation/AuthMemberController.java new file mode 100644 index 0000000..58a7dff --- /dev/null +++ b/Second Seminar/SecondSeminar/src/main/java/com/example/SecondSeminar/member/presentation/AuthMemberController.java @@ -0,0 +1,31 @@ +package com.example.SecondSeminar.member.presentation; + +import com.example.SecondSeminar.member.application.AuthMemberService; +import com.example.SecondSeminar.member.dto.request.AuthMemberRequest; +import java.net.URI; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RequestMapping("/api/users/") +@RequiredArgsConstructor +@RestController +public class AuthMemberController { + + private final AuthMemberService authMemberService; + + @PostMapping("sign-up") + public ResponseEntity<Void> signUp(@RequestBody AuthMemberRequest request) { + URI location = URI.create(authMemberService.create(request)); + return ResponseEntity.created(location).build(); + } + + @PostMapping("sign-in") + public ResponseEntity<Void> signIn(@RequestBody AuthMemberRequest request) { + authMemberService.signIn(request); + return ResponseEntity.noContent().build(); + } +}