Spring Security 회원가입

바그다드·2023년 4월 2일
0

Spring Security

목록 보기
3/17
  • 앞서 권한이 필요한 페이지와 권한이 필요하지 않는 페이지를 구분하여 구현을 하였다.
    이제 권한이 필요한 페이지 요청이 들어오면 로그인 폼을 거치도록 구현해보자!!

IndexController 수정

  • 기존 login페이지를 loginForm페이지로 변경하고 @ResponseBody제거
@GetMapping("/loginForm")
    public String loginForm() {
        return "loginForm";

loginForm.html 생성

<!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();
    }

loginForm.html 수정

  • 회원가입 페이지로 이동하는 링크 추가
...
</form>
<!-- 회원가입 링크 -->
<a href="/joinForm">회원가입을 아직 하지 않으셨나요?</a>
...

joinForm.html 생성

  • 회원가입 폼
<!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";
    }
  • 이렇게 하면 암호가 인코딩되어 저장된다!!
profile
꾸준히 하자!

0개의 댓글