<signup.jsp> 파일
<form class="login__input" action="/auth/signup" method="post">
<input type="text" name="username" placeholder="유저네임" required="required" />
<input type="password" name="password" placeholder="패스워드" required="required" />
<input type="email" name="email" placeholder="이메일" required="required" />
<input type="text" name="name" placeholder="이름" required="required"/>
<button>가입</button>
</form>
이러면 웹 사이트상에
이렇게 회원가입 화면이 나온다.
그래서 사용자가 유저네임, 패스워드, 이메일, 이름을 입력하고
가입 버튼을 누르면
<SignupDto.java> 파일
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import lombok.Data;
@Data
public class SignupDto {
@Size(min = 2, max = 20)
@NotBlank
private String username;
@NotBlank
private String password;
@NotBlank
private String email;
@NotBlank
private String name;
SignupDto.java 파일에서 사용자가 입력한 값들(username, password, email, name) 을 받는다.
스프링은
form 으로 데이터가 들어오면 (jsp 파일에서 form 태그)
(x-www-form-urlencoded 방식) 즉, key = value 형식으로 들어옴
(@Size, @NotBlank 는 값 입력시 글자 크기가 최소 2 ~20 사이, 빈칸이 입력되지 않도록 유효성 검사를 한 것으로,
https://happy-fun.tistory.com/152
회원가입 유효성 검사
회원가입 시 username password email name 값을 받도록 만들었다. 즉, 회원가입 페이지는 아래처럼 되어 있다. 이 모든 값들을 사용자가 입력해야 만 회원가입이 가능하게 하려고 한다. 그러면 2가지 처
happy-fun.tistory.com
이 글을 읽어보면 된다.)
그러면 AuthController.java에서 이를 받아서 회원가입 처리 한다.
그런데, signupdto.java 는 사용자가 웹 사이트에 입력한 값을 받아오는 오브젝트이고,
이를 데이터베이스에 저장하려면,
User.java 오브젝트를 만들어서 signupdto.java에서 받은 데이터를 이곳(User.java) 에 담아야 한다.
그리고 이를 repository로 전달해줘서 데이터베이스에 저장하도록 해야 한다.
즉, 웹 사이트에서 사용자가 회원가입 페이지에 입력한 정보를 받아오는 것은
SignupDto.java 파일이고,
이렇게 받아온 정보를 데이터 베이스에 저장할 때 사용되는 것은
User.java 파일이다.
<User.java> 파일
import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.PrePersist;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(length = 100, unique = true)
private String username;
@Column(nullable = false)
private String password;
@Column(nullable = false)
private String name;
private String website; // 웹 사이트
private String bio; // 자기 소개
@Column(nullable = false)
private String email;
private String phone;
private String gender;
private String role; // 권한
private String profileImageUrl;
private LocalDateTime createDate;
@PrePersist
public void createDate() {
this.createDate = LocalDateTime.now();
}
}
여기에 보면, 우리는 username, password, email, name 만 사용자로부터 받았지만, website 등 다른 변수가 user.java 오브젝트에 있는 것을 알 수 있다.
(최종적으로 데이터베이스에는 username, password, name, email, website, bio, phone 등 모든 변수가 테이블로 만들어진다.)
아무튼, 그래서 SignupDto.java에 사용자로부터 받은 데이터들을 User.java 오브젝트로 만들기 위해 SignupDto.java 파일에서 toEntity 메서드를 만든다. (빌더 패턴 사용- User.java에서 @Builder 어노테이션 사용)
어노테이션 설명:
@PrePersist
db 에 값이 insert 되기 직전에 실행
즉, createDate 부분은 자동으로 db에 들어감
@Entity
db에 테이블 생성해줌
@GeneratedValue(strategy = GenerationType.IDENTITY)
번호 증가 전략이 데이터베이스를 따라감
<SignupDto.java> 파일
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import com.tree.sky.domain.user.User;
import lombok.Data;
@Data
public class SignupDto {
@Size(min = 2, max = 20)
@NotBlank
private String username;
@NotBlank
private String password;
@NotBlank
private String email;
@NotBlank
private String name;
public User toEntity() {
return User.builder()
.username(username)
.password(password)
.email(email)
.name(name)
.build();
}
}
그런 다음 AuthController.java에서
SignupDto.java의 toEntity로 만들어진 user 오브젝트를 데이터베이스에 저장하도록 코드를 만든다.
<AuthController.java> 파일
@RequiredArgsConstructor
@Controller
public class AuthController {
private final AuthService authService;
@PostMapping("/auth/signup")
public String signup(@Valid SignupDto signupDto, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
Map<String, String> errorMap = new HashMap<>();
for (FieldError error : bindingResult.getFieldErrors()) {
errorMap.put(error.getField(), error.getDefaultMessage());
}
throw new CustomValidationException("유효성 검사 실패함", errorMap);
}else {
User user = signupDto.toEntity();
authService.회원가입(user);
return "auth/signin";
}
}
}
여기서 보면 signupDto.toEntity로 user 오브젝트를 받고,
authService 객체의 회원가입 메서드로 회원가입을 완성하는 것을 알 수 있다.
(더불어 이 코드에서 @Valid, BindingResult, 관련한 코드는 회원가입 유효성 관련 코드로,
https://happy-fun.tistory.com/152
회원가입 유효성 검사
회원가입 시 username password email name 값을 받도록 만들었다. 즉, 회원가입 페이지는 아래처럼 되어 있다. 이 모든 값들을 사용자가 입력해야 만 회원가입이 가능하게 하려고 한다. 그러면 2가지 처
happy-fun.tistory.com
이 글을 읽어 보면 된다.)
(또한 AuthController.java에서 AuthService 객체의 회원가입 메서드를 사용할 떄, 의존성 주입이 필요한데 이에 대한 설명은 아래의 글을 참고하면 된다.
https://happy-fun.tistory.com/156
의존성 주입
프로젝트에서 회원가입 코드를 만들 때, AuthController.java 에서 AuthService.java의 회원가입 메서드를 사용하려고 한다면 AuthController.java에 AuthService 오브젝트를 의존성 주입해야 한다. 즉, 아래에서..
happy-fun.tistory.com
)
<AuthService.java> 파일
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.tree.sky.domain.user.User;
import com.tree.sky.domain.user.UserRepository;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Service
public class AuthService {
private final UserRepository userRepository;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
@Transactional
public User 회원가입(User user) throws RuntimeException{
String rawPassword = user.getPassword();
String encPassword = bCryptPasswordEncoder.encode(rawPassword);
user.setPassword(encPassword);
user.setRole("ROLE_USER"); // 관리자 ROLE_ADMIN
User userEntity = null;
userEntity = userRepository.save(user);
return userEntity;
}
}
여기서 회원가입 메서드를 확인할 수 있다.
특히, 비밀번호 해쉬를 위해
일단 AuthController.java에서 받아온 user 객체에서 비밀번호를
rawPassword 변수로 받고,
bCryptPasswordEncoder로 해쉬화 해준다음 다시 user 오브젝트에 넣어주는 것을 알 수 있다.
그리고 권한은, 관리자 권한을 주기 위해 ROLE_USER 로 넣어주었다.
그런다음, userEntity User 객체를 만들어줘서, repository에 저장하고 난 다음의 회원 정보를 받는다.
return userEntity로 받고 있고,
AuthController.java에서도 보면 return "auth/signin" 하고 있는 거로 보아,
signin.jsp 파일에서 이 사용자 정보를 활용해서 signin.jsp 화면에서 사용할 것임을 알 수 있다.
@Service
ioc 관리, 트랜잭션 관리
<UserRepository.java> 파일
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User,Integer>{
User findByUsername(String username);
}
특히, respotiroy.java의 경우는, JpaRepository를 상속하면
어노테이션 없어도 IoC 등록이 자동으로 됨
이렇게 하면 회원가입이 완료된다.
-끝-
<추가 설명>
회원가입 시
username, password, email, name 값을 사용자로부터 받을 건데,
이렇게 받은 값을 SignupDto.java 파일에 받아서
AuthController.java 파일에 회원가입 함수에 매개변수로 넣어줄 거임.
<SignupDto.java> 파일
@Data
public class SignupDto {
private String username;
private String password;
private String email;
private String name;
어노테이션 설명 :
@Data : Getter, Setter를 만들어주는 어노테이션
그런데, 회원정보가 잘 들어오는지 확인하기 위해,
log를 사용할 수 있음
즉, AuthController.java 파일에서
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@RequiredArgsConstructor
@Controller
public class AuthController {
private static final Logger log = LoggerFactory.getLogger(AuthController.class);
@PostMapping("/auth/signup")
public String signup(SignupDto signupDto) {
log.info(signupDto.toString());
return "auth/signin";
}
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger log = LoggerFactory.getLogger(AuthController.class); 선언 후에
log.info(signupDto.toString());
이렇게 사용하면, 이클립스(sts) 콘솔창에 사용자가 입력한 회원가입 정보가 들어옴
이런식으로 사용자가 회원가입 때 입력한 username, password, email, name 값을 볼 수 있음
만약에, SignupDto.java의 toString()메서드로 받아온 User 객체를 확인하고 싶다면,
AuthController.java 에서
1. log.info(signupDto.toString());
이 코드 아래에
User user = signupDto.toEntity();
2. log.info(user.toString());
이 코드를 추가하면 된다.
@PostMapping("/auth/signup")
public String signup(SignupDto signupDto) {
log.info(signupDto.toString());
User user = signupDto.toEntity();
log.info(user.toString());
return "auth/signin";
}
}
그러면 아래와 같이 웹사이트상에서 사용자가 회원가입을 하면
이클립스(sts) 콘솔창에
1, 2 가 실행된 두 개의 결과를 볼 수 있다.
참고 자료 : 이지업 강의 사이트 "스프링부트 SNS프로젝트 - 포토그램 만들기"