- 앞서 권한이 필요한 페이지와 권한이 필요하지 않는 페이지를 구분하여 구현을 하였다.
이제 권한이 필요한 페이지 요청이 들어오면 로그인 폼을 거치도록 구현해보자!!
IndexController 수정
- 기존 login페이지를 loginForm페이지로 변경하고 @ResponseBody제거
@GetMapping("/loginForm")
public String loginForm() {
return "loginForm";
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>로그인 페이지</title>
</head>
<body>
<h1>
로그인 페이지
</h1>
<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>
- 그런데 로그인을 하려면 먼저 회원가입부터 해야한다
user 테이블
- model 패키지를 만들어 거기에 User클래스 생성
@Entity
@Data
public class User {
@Id
@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;
}
IndexController 수정
@GetMapping("/joinForm")
public String joinForm() {
return "joinForm";
}
SecurityConfig 수정
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers("/user/**").authenticated() // user 페이지에는 권한 필요
.antMatchers("/manager/**").access("hasRole('ROLE_MANAGER') or hasRole('ROLE_ADMIN')") // manager페이지에 필요한 권한
.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')") // admin페이지에 필요한 권한
.anyRequest().permitAll() // 모든 요청은 권한 허가
// 추가
.and()
.formLogin()
.loginPage("/loginForm"); // 이 부분 수정******
return http.build();
}
...
</form>
<a href="/joinForm">회원가입을 아직 하지 않으셨나요?</a>
...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>회원가입 페이지</title>
</head>
<body>
<h1>
회원가입 페이지
</h1>
<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>
UserRepository 생성
- repository 패키지 아래 UserRepository를 생성하자
public interface UserRepository extends JpaRepository<User, Integer> {
}
- 왜 @Repository를 사용하지 않았을까?
- JpaRepository를 상속받는 인터페이스는 자동으로 IOC컨테이너에 등록이 된다!
IndexController 수정
private UserRepository userRepository;
public IndexController(UserRepository userRepository) {
this.userRepository = userRepository;
}
@PostMapping ("/join")
public String join(User user){
System.out.println(user);
user.setRole("ROLE_USER");
userRepository.save(user);
return "join"; //실제회원가입
}
- 그런데 이렇게만 하면 spring Security로 회원가입을 할 수 없는데, 그 이유는 비밀번호가 인코딩이 안되어 있기 때문이다.
SecurityConfig 수정
// 패스워드를 암호화 시켜주는 객체
@Bean
public BCryptPasswordEncoder encodePwd() {
return new BCryptPasswordEncoder();
}
IndexController 수정
private UserRepository userRepository;
private BCryptPasswordEncoder bCryptPasswordEncoder;
public IndexController(UserRepository userRepository, BCryptPasswordEncoder bCryptPasswordEncoder) {
this.userRepository = userRepository;
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
}
@PostMapping("/join")
public String join(User user) {
System.out.println(user);
user.setRole("ROLE_USER");
String rawPassword = user.getPassword();
String encPassword = bCryptPasswordEncoder.encode(rawPassword);
user.setPassword(encPassword);
userRepository.save(user);
return "redirect:/loginForm";
}
- 이렇게 하면 암호가 인코딩되어 저장된다!!