Spring Boot

Spring Boot Security 회원가입 Form

박도치 2023. 6. 2. 14:01

간단한 회원가입 Form을 만드는 과정이다. 

 

먼저 Controller 는 loginForm과 joinForm , join 세 가지를 만드는데 loginForm은 로그인페이지 및 로그인, joinForm은 회원가입페이지 join은 회원가입 진행 (POST)을 만듭니다.

 

패키지 및 클래스

 

join 쪽에서 해줘야 할 일은 회원가입 진행인데 회원가입은 id, password, email 세가지를 위 joinForm 에서 만들었다.

 

필요한건 User를 담을 클래스와 create 해줄 UserRepository 인터페이스가 필요하다.

 

JPA를 사용할 것이기 때문에 기존에 Service와 mapper형식이 아닌 JpaRepository를 extends하여 인터페이스를 만들것이다.

 

model패키지 내의 User 클래스

@Entity
@Data
public class User {

	@Id //PrimaryKey
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private int id;
	private String username;
	private String password;
	private String email;
	private String role;// ROLE_USER, ROLE_ADMIN
	
	@CreationTimestamp
	private Timestamp createDate; //java.sql import
	
	
}

jpa를 통해 @Entity를 알아서 관리해주고, getter setter를 사용하기 위해 @Data를 붙였다.

 

Jpa를 이용하면 DB에 간단하게 테이블을 생성하고 CRUD함수를 사용할 수 있다.

 

DB에 테이블이 생성됨

 

repository 패키지의 UserRepository

//CRUD 함수를 JpaRepository가 들고있음
//@Repository 라는 어노테이션이 없어도 IoC에 등록이 된다. JpaRepository를 상속했기 때문이다.
public interface UserRepository extends JpaRepository<User, Integer>{

}

 

아래는 로그인 회원가입 html파일이다.

 

LoginForm 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인 페이지</title>
</head>
<body>
<h1>로그인페이지</h1>
<hr/>
<form>
	<input type="text" name="username" placeholder="Username"><br/>
	<input type="password" name="password" placeholder="Password"><br/>
	<button>로그인</button>
</form>
<a href="/joinForm">회원가입을 아직 하지않으셨나요?</a>	
</body>
</html>

 

joinForm

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원가입 페이지</title>
</head>
<body>
<h1>회원가입 페이지</h1>
<hr/>
<form action="/join" method="POST">
	<input type="text" name="username" placeholder="Username"><br/>
	<input type="password" name="password" placeholder="Password"><br/>
	<input type="email" name="email" placeholder="Email"><br/>
	<button>회원가입</button>
</form>
</body>
</html>

 

컨트롤러에는 GET요청으로 html을 return해줄 loginForm joinForm 그리고 POST요청을 return해줄 join 컨트롤러가 필요하다.

 

Contorller

@Controller
@RequiredArgsConstructor
public class IndexController {

	private final UserRepository userRepository;
	
	//spring security가 낚아챔
	@GetMapping("/loginForm")
	public String login() {
		return "loginForm";
	}
	
	@GetMapping("/joinForm")
	public String joinForm() {
		return "joinForm";
	}
	
	
	@PostMapping("/join")
	public String join(User user) {
		System.out.println(user);
		user.setRole("ROLE_USER");
		
		userRepository.save(user); // 회원가입이 잘되지만 패스워드가 암호화가 안됐기 때문에 시큐리티로 로그인할 수 없다.
		return "redirect:/loginForm"; // return을 loginForm으로 해줌 계정이 로그인되어있지 않으면 로그인페이지로 redirect를 해주면 좋기 때문이다.
	}

 

로그인 시도

joinForm페이지를 호출하여 id 는 user, 비밀번호는 1234로 진행했다.

 

DB에 확인한 결과 user 와 비밀번호 1234가 잘 들어온것을 볼 수 있다.

 

하지만 이렇게 회원가입을 한다면 가능은 하지만 암호화가 된것이 아니기 때문에 Security로 로그인 할 수 없고 비밀번호가 너무 쉽게 노출될 우려가 있다. 

 

암호화는 springboot main application에 Bean으로 BCryptPasswordEncoder 를 등록한 후 가져와서 사용하면 된다.

 

SpringBoot main Application

 

@SpringBootApplication
public class OauthTestApplication {

	@Bean
	BCryptPasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}
	
	public static void main(String[] args) {
		SpringApplication.run(OauthTestApplication.class, args);
	}

}

위와같이 Bean에 BCryptPasswordEncoder 를 등록한 후 Controller로 가져와서 사용하면 된다.

 

수정된 Controller

@Controller
@RequiredArgsConstructor
public class IndexController {

	private final UserRepository userRepository;
	private final BCryptPasswordEncoder passwordEncoder; //Bean에 등록한 BCryptPasswordEncoder 가져옴 
	
	//spring security가 낚아챔
	@GetMapping("/loginForm")
	public String login() {
		return "loginForm";
	}
	
	@GetMapping("/joinForm")
	public String joinForm() {
		return "joinForm";
	}
	
	
	@PostMapping("/join")
	public String join(User user) {
		System.out.println(user);
		user.setRole("ROLE_USER");
		String rawPassword = user.getPassword();
		String encPassword = passwordEncoder.encode(rawPassword);
		user.setPassword(encPassword); //회원가입시 password를 get해온 후 인코딩 하여 다시 set해주는 과정 
		
		userRepository.save(user); // 회원가입이 잘되지만 패스워드가 암호화가 안됐기 때문에 시큐리티로 로그인할 수 없다.
		return "redirect:/loginForm"; // return을 loginForm으로 해줌 계정이 로그인되어있지 않으면 로그인페이지로 redirect를 해주면 좋기 때문이다.
	}

 

이렇게하면 암호화하여 회원가입을 할 수 있다.