단 하나의 맥락
: 회원 가입 기능 추가 및 적용
Semiflow Bundle
- 회원 가입을 위한 Entity 생성
- UserRepository 작성
- BcryptPasswordEncoder를 사용한 Service 작성
- UserCreateForm으로 속성 제한
- UserController 작성
- 회원가입 template 작성
- 네비게이션 바에 회원가입 링크 추가하기
- 중복 회원가입 status=500 처리
Entity 생성
> com.mysite.sbb.user 패키지에 SiteUser.java 신규 작성
@Entity @Getter @Setter
public class SiteUser {}
- @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Long id;
- @Column(unique = true)
- private String username;
- private String password;
- @Column(unique = true)
- private String email;
-
리포지터리 생성
> UserRepository.java 신규 작성
// import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<SiteUser, Long> {}
-
서비스 작성
> UserService.java 신규 작성
// import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@RequiredArgsConstructor
@Service
public class UserService {}
- private final UserRepository userRepository;
- M : public SiteUser create // S : (String username, String email, String password)
- A1 : SiteUser user = new SiteUser();
- A2 : user.setUsername(username);
- A3 : user.setEmail(email);
- A4 : BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
- A5 : user.setPassword(passwordEncoder.encode(password));
- A6 : this.userRepository.save(user);
- A7 : return.user;
* 더 나은 버전
BCryptPasswordEncoder 객체를 직접 생성하여 사용하지 않고 빈으로 등록한 PasswordEncoder 객체를 주입받아 사용하도록
> SecurityConfig에서
@Bean
- M : public PasswordEncoder passwordEncoder() {}
- A1 : return new BCryptPasswordEncoder();
// import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
// import org.springframework.security.crypto.password.PasswordEncoder;
-
> UserService에서
- private final PasswordEncoder passwordEncoder; 추가
// import org.springframewok.security.crypto.password.PasswordEncoder;
- A4 :
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();삭제
-
폼 작성
> UserCreateForm.java 신규 작성
@Getter @Setter
public class UserCreateForm {}
- @Size(min = 3, max = 25)
- @NotEmpty(message = "사용자 Id는 필수 항목입니다")
- private String username;
- @NotEmpty(message = "비밀번호는 필수항목입니다")
- private String password1;
- @NotEmpty(message = "비밀번호 확인은 필수항목입니다")
- private String password2;
- @NotEmpty(message = "이메일은 필수항목입니다")
- private String email;
// import javax.validation.constraints.Email;
-
컨트롤러 작성으로 회원가입 폼 띄우기
@RequiredArgsConstructor
@Controller
@RequestMapping("/user")
public class UserController{}
- private final UserService userService;
- @GetMapping("/signup")
- M : public String signup{}
- S : (UserCreateForm userCreateForm)
- A1 : return "singup_form";
- @PostMapping("/signup")
- M & S : public String signup(@Valid UserCreateForm userCreateForm, BindingResult bindingResult) {}
- A1 : if (bindingResult.hasErrors()) { return "signup_form"; }
- A2 : if (!userCreateForm.getPassword1().equals(userCreateForm.getPassword2())) {}
- bindingResult.rejectValue("password2", "passwordInCorrect", "2개의 패스워드가 일치하지 않습니다" );
- return "signup_form";
- A3 : userService.create(userCreateForm.getUsername()), userCreateForm.getEmail(), userCreateForm.getPassword1());
- A4 : return "redirect:/";
-
회원가입 템플릿 작성
> signup_form.html 신규 작성
틀
- <html layout:decorate="~{layout}"></html> 내부
- <div layout:frament="content" class="container my-3"></div>로 플러그인 틀 잡은 다음
제목
- <div class="my-3 border-bottom"></div> 내부
- <div></div> 내부 <h4>회원가입</h4>
본문 : 4가지 작성 폼
- <form th:action="@{/user/signup}" th:object="${userCreateForm}" method="post"></form> 내부
- 최상단 <div th:replace="form-errors :: formErrorsFragment"></div> 에러메세지 P/I 연결
- 최하단 <button type="submit" class="btn btn-primary">회원가입</button> 버튼 구현
- <div class="mb-3"></div> 내에
- <label for="username" class="form-label">사용자ID</label>
- <input type="text" th:field="*{username}" class="form-control">
- <div class="mb-3"></div> 내에
- <label for="password1" class="form-label">비밀번호</label>
- <input type="password" th:field="*{password1}"> class="form-control">
- <div class="mb-3"></div> 내에
- <label for="password2" class="form-label">비밀번호 확인</label>
- <input type="password" th:field="*{password2}" class="form-control">
- <div class="mb-3"></div> 내에
- <label for="email" class="form-label">이메일</label>
- <input type="email" th:field="*{email}" class="form-control">
-
Navigation bar에 회원가입 링크 추가
> navbar.html 에서
- <li class="nav-item"></li> 내부
- <a class="nav-link" href="#">로그인</a>
하단에
- <li class="nav-item"></li> 내부
- <a class="nav-link" th:href="@{/user/signup}">회원가입</a>
-
중복 회원가입 status=500 처리
> UserController에서 A3 부분을 처리한다
A3 :
- try {
- M : userService.create()
- userCreateForm.getUsername(),
- userCreateForm.getEmail(),
- userCreateForm.getPassword1();
- } catch(DateIntegrityViolationException e) {
- A1 : e.printStackTrace();
- A2 : bindingResult.reject("signupFailed", "이미 등록된 사용자입니다");
- A3 : return "signup_form";
- } catch(Exception e) {
- A1 : e.printStackTrace();
- A2 : bindingResult.reject("signupFailed", e.getMessage());
- A3 : return "signup_form";
// import org.springframework.dao,DataIntegrityViolationException;
> 이메일 주소가 동일할 경우(DateIntegrityViolationException 발생) 500 페이지 대신 및 해당 메세지 출력
> 다른 오류의 경우 해당 오류의 메세지 출력
'포트폴리오 > SPRINGBOOT 옛날' 카테고리의 다른 글
3-08 : entity에 author 추가하기 (0) | 2022.10.10 |
---|---|
3-07 : 로그인과 로그아웃 (0) | 2022.10.09 |
3-05 : spring security (3) | 2022.10.09 |
3-04 : 답변 갯수 표시 (0) | 2022.10.09 |
3-03 : 일련번호 추가 수정 (0) | 2022.10.09 |