※순서
1. 회원 엔티티 구현__________________(User.java)
2. 회원 리포지터리, 서비스 구현_________(UserRepository.java, UserService.java)
3. DTO 구현_______________________ (UserCreateForm.java)
4. 회원 컨트롤러 구현_________________(UserController.java)
5. 회원가입 화면 구현_________________(signup_form.html)
6. 중복 회원가입 방지
1. 회원 엔티티 구현
User.java
package com.mysite.sbb.user;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Entity
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;
}
여기서 아이디(username)이랑 이메일(email)은 중복되면 안되기 때문에 (unique = true) 로 설정
2. 회원 리포지터리, 서비스 구현
UserRepository.java
package com.mysite.sbb.user;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<SiteUser, Long> {
}
SecurityConfig.java 수정 (PasswordEncoder 객체를 빈으로 등록)
BCryptPasswordEncoder 객체를 직접 new 로 생성하는 방식으로 할 경우 암호화 방식을 변경하면
BCryptPasswordEncoder 을 사용한 모든 프로그램을 찾아 수정해야하기 때문에 빈으로 등록하는 것을 추천
(... 생 략 ...)
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
(... 생 략 ...)
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorizeHttpRequests) ->
authorizeHttpRequests
.requestMatchers(new AntPathRequestMatcher("/**")).permitAll());
return http.build();
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
UserService.java
package com.mysite.sbb.user;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Service
public class UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
public SiteUser create(String username, String email, String password) {
SiteUser user = new SiteUser();
user.setUsername(username);
user.setEmail(email);
user.setPassword(passwordEncoder.encode(password));
this.userRepository.save(user);
return user;
}
}
3. DTO 구현
UserCreateForm.java
package com.mysite.sbb.user;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Size;
import lombok.Getter;
import lombok.Setter;
@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 = "이 메 일 은 필 수 항 목 입 니 다.")
@Email
private String email;
}
4. 회원 컨트롤러 구현
UserController.java
package com.mysite.sbb.user;
import jakarta.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Controller
@RequestMapping("/user")
public class UserController {
private final UserService userService;
@GetMapping("/signup")
public String signup(UserCreateForm userCreateForm) {
return "signup_form";
}
@PostMapping("/signup")
public String signup(@Valid UserCreateForm userCreateForm, BindingResult bindingResult)
{
if (bindingResult.hasErrors()) {
return "signup_form";
}
if (!userCreateForm.getPassword1().equals(userCreateForm.getPassword2())){
bindingResult.rejectValue("password2", "passwordInCorrect",
"2개 의 패 스 워 드 가 일 치 하 지 않 습 니 다.");
return "signup_form";
}
userService.create(userCreateForm.getUsername(),
userCreateForm.getEmail(), userCreateForm.getPassword1());
return "redirect:/";
}
}
5. 회원가입 화면 구현
signup_form.html
<html layout:decorate="~{layout}">
<div layout:fragment="content" class="container my-3">
<div class="my-3 border-bottom">
<div>
<h4>회 원 가 입</h4>
</div>
</div>
<form th:action="@{/user/signup}" th:object="${userCreateForm}" method="post">
<div th:replace="~{form_errors :: formErrorsFragment}"></div>
<div class="mb-3">
<label for="username" class="form-label">사 용 자ID</label>
<input type="text" th:field="*{username}" class="form-control">
</div>
<div class="mb-3">
<label for="password1" class="form-label">비 밀 번 호</label>
<input type="password" th:field="*{password1}" class="form-control">
</div>
<div class="mb-3">
<label for="password2" class="form-label">비 밀 번 호 확 인</label>
<input type="password" th:field="*{password2}" class="form-control">
</div>
<div class="mb-3">
<label for="email" class="form-label">이 메 일</label>
<input type="email" th:field="*{email}" class="form-control">
</div>
<button type="submit" class="btn btn-primary">회 원 가 입</button>
</form>
</div>
</html>
6. 중복 회원가입 방지
UserController.java 수정
package com.mysite.sbstudy.user;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.dao.DataIntegrityViolationException;
@RequiredArgsConstructor
@Controller
@RequestMapping("/user")
public class UserController {
private final UserService userService;
@GetMapping("/signup")
public String signup(UserCreateForm userCreateForm){
return "signup_form";
}
@GetMapping("/login")
public String login(){
return "login_form";
}
@PostMapping("/signup")
public String signup(@Valid UserCreateForm userCreateForm,
BindingResult bindingResult){
if(bindingResult.hasErrors()){
return "signup_form";
}
if(!userCreateForm.getPassword1().equals(userCreateForm.getPassword2())) {
bindingResult.rejectValue("password2", "passwordIncorrect",
"2개의 패스워드가 일치하지 않습니다.");
return "signup_form";
}
try{
userService.create(userCreateForm.getUsername(),
userCreateForm.getEmail(), userCreateForm.getPassword1());
}
catch(DataIntegrityViolationException e){
e.printStackTrace();
bindingResult.reject("signupFailed",
"이 미 등 록 된 사 용 자 입 니 다.");
return "signup_form";
}
catch(Exception e) {
e.printStackTrace();
bindingResult.reject("signupFailed", e.getMessage());
return "signup_form";
}
return "redirect:/";
}
}
'SpringBoot > 스프링시큐리티' 카테고리의 다른 글
스프링 시큐리티 - 로그인 기능 (0) | 2024.07.16 |
---|---|
스프링 시큐리티 - 설치 및 설정 (0) | 2024.07.16 |