Implement Sign Up without Security

This commit is contained in:
hou27
2022-05-18 00:02:49 +09:00
commit 1dbd823b2a
20 changed files with 825 additions and 0 deletions

View File

@@ -0,0 +1,19 @@
package demo.api;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@SpringBootApplication
/**
* 스프링 부트의 Entry 포인트 클래스에
* @EnableJpaAuditing 어노테이션을 적용하여 JPA Auditing을 활성화
*/
@EnableJpaAuditing
public class ApiApplication {
public static void main(String[] args) {
SpringApplication.run(ApiApplication.class, args);
}
}

View File

@@ -0,0 +1,31 @@
package demo.api;
import demo.api.user.UserService;
import demo.api.user.UserServiceImpl;
import demo.api.user.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
private final UserRepository userRepository;
public AppConfig(UserRepository userRepository) {
System.out.println("AppConfig");
System.out.println("userRepository = " + userRepository);
this.userRepository = userRepository;
}
@Bean
public UserService userService() {
System.out.println("userService");
return new UserServiceImpl(userRepository);
}
// @Bean
// public BCryptPasswordEncoder passwordEncoder() {
// System.out.println("passwordEncoder");
// return new BCryptPasswordEncoder();
// }
}

View File

@@ -0,0 +1,44 @@
package demo.api.common.domain;
import java.time.LocalDate;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@Getter @Setter
/**
* JPA Entity 클래스들이 CoreEntity 추상 클래스를 상속할 경우
* createDate, modifiedDate를 컬럼으로 인식하도록
* MappedSuperclass 어노테이션을 추가
*/
@MappedSuperclass
/**
* Spring Data JPA에서 시간에 대해서 자동으로 값을 넣어주는 기능인
* JPA Audit를 사용하기 위해 아래 줄을 통해
* CoreEntity 클래스에 Auditing 기능을 포함
*
* 그리고
* 스프링 부트의 Entry 포인트 클래스에
* @EnableJpaAuditing 어노테이션을 적용하여 JPA Auditing을 활성화
*/
@EntityListeners({AuditingEntityListener.class})
public class CoreEntity {
@CreatedDate
private LocalDate createdAt;
@LastModifiedDate
private LocalDate updateAt;
@Id // 이 프로퍼티가 pk 역할을 한다는 것을 명시
@Column(name = "id") // 객체 필드와 DB 테이블 컬럼을 맵핑
@GeneratedValue(strategy= GenerationType.IDENTITY) // @GeneratedValue는 pk의 값을 위한 자동 생성 전략을 명시하는데 사용
private Long id;
}

View File

@@ -0,0 +1,35 @@
package demo.api.user;
import demo.api.user.domain.User;
import demo.api.user.dtos.UserSignUpRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* User 관련 HTTP 요청 처리
*/
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@PostMapping("/signUp")
public Boolean signUp(@ModelAttribute @Validated UserSignUpRequest signUpReq) throws Exception {
if(userService.isEmailExist(signUpReq.getEmail())) {
throw new Exception("Your Mail already Exist.");
}
User newUser = userService.signUp(signUpReq.toUserEntity());
System.out.println("newUser = " + newUser.toString());
if(newUser.getId() != null) {
System.out.println("running");
return true;
}
return false;
}
}

View File

@@ -0,0 +1,34 @@
package demo.api.user;
import demo.api.user.domain.User;
public interface UserService {
/**
* 유저의 정보로 회원가입
* @param user 가입할 유저의 정보
* @return 가입된 유저 정보
*/
User signUp(User user);
/**
* 이메일을 통해 유저 조회
* @param email
* @return 조회된 유저
*/
User findUserByEmail(String email);
/**
* 유저 정보 수정
* @param user 수정활 User Entity
* @param newInfo
* @return 수정된 User
*/
User updateUser(User user, String newInfo);
/**
* 이메일 중복 여부를 확인
* @param email
* @return true | false
*/
boolean isEmailExist(String email);
}

View File

@@ -0,0 +1,36 @@
package demo.api.user;
import demo.api.user.domain.User;
import demo.api.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
@Transactional
public class UserServiceImpl implements UserService {
// private final BCryptPasswordEncoder passwordEncoder;
private final UserRepository userRepository;
@Override
public User signUp(User user) {
// user.hashPassword(passwordEncoder);
return userRepository.save(user);
}
@Override
public User findUserByEmail(String email) {
return null;
}
@Override
public User updateUser(User user, String newInfo) {
return null;
}
@Override
public boolean isEmailExist(String email) {
return false;
}
}

View File

@@ -0,0 +1,54 @@
package demo.api.user.domain;
import demo.api.common.domain.CoreEntity;
import javax.persistence.Column;
import javax.persistence.Entity;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
//import org.springframework.security.crypto.password.PasswordEncoder;
// @Entity 어노테이션을 클래스에 선언하면 그 클래스는 JPA가 관리
@Entity
@Getter @Setter
@NoArgsConstructor
@ToString
public class User extends CoreEntity {
@Column(nullable = false, unique = true)
private String email;
@Column(nullable = false)
private String password;
@Column(length = 10, nullable = false)
private String name;
@Builder
public User(String email, String password, String name) {
this.email = email;
this.password = password;
this.name = name;
}
// https://reflectoring.io/spring-security-password-handling/
/**
* 비밀번호를 암호화
* @param passwordEncoder 암호화 할 인코더 클래스
* @return 변경된 유저 Entity
*/
// public User hashPassword(PasswordEncoder passwordEncoder) {
// this.password = passwordEncoder.encode(this.password);
// return this;
// }
/**
* 비밀번호 확인
* @param plainPassword 암호화 이전의 비밀번호
* @param passwordEncoder 암호화에 사용된 클래스
* @return true | false
*/
// public boolean checkPassword(String plainPassword, PasswordEncoder passwordEncoder) {
// System.out.println("checkPW");
// return passwordEncoder.matches(plainPassword, this.password);
// }
}

View File

@@ -0,0 +1,32 @@
package demo.api.user.dtos;
import demo.api.user.domain.User;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter @Setter
public class UserSignUpRequest {
@NotEmpty(message = "Please enter your Email")
@Email
private String email;
@NotEmpty(message = "Please enter your Password")
private String password;
@NotEmpty(message = "Please enter your Name")
private String name;
/**
* Transform to User Entity
* @return User Entity
*/
public User toUserEntity() {
return User.builder()
.email(this.getEmail())
.password(this.getPassword())
.name(this.getName())
.build();
}
}

View File

@@ -0,0 +1,14 @@
package demo.api.user.repository;
import demo.api.user.domain.User;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
// @Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByEmail(String email);
boolean existsByEmail(String email);
}