Spring security session방식 - 회원가입 (2)

2025. 2. 17. 16:50Springboot/security

 

이전 글에서 SecurityConfig를 다음과 같이 작성했다.

@Configuration   //Spring에서 설정 파일임을 나타냄.
@EnableWebSecurity
//Spring Security의 보안 설정을 활성화하는 애너테이션(annotation)
// Spring Boot 2에서는 필수였지만, Spring Boot 3에서는 생략가능. but security설정임을 명시
public class SecurityConfig {

    @Bean //security는 password를 DB에 저장할 때 인코딩해서 저장.  비교할 때는 디코딩 후 비교.
    public PasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityFilterChain filterChain1(HttpSecurity http) throws Exception{
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/h2-console/**").permitAll() // H2 콘솔 접근 허용
            )
            .csrf(csrf -> csrf.ignoringRequestMatchers("/h2-console/**")) // H2 콘솔 CSRF 비활성화
            .headers(headers -> headers.frameOptions(frame -> frame.disable())); // H2 콘솔을 iframe에서 허용

        http.authorizeHttpRequests((auth) -> auth
            .requestMatchers("/join/**", "/login").permitAll()    // 이 url들은 로그인 안해도됨
            .requestMatchers("/admin").hasAuthority("ADMIN")   //ADMIN 권한 사용자만
            .requestMatchers("/my/**").hasAnyAuthority("ADMIN", "USER")  // ADMIN, USER 권한 중 하나 가지면 ㅇㅋ
            .anyRequest().authenticated()   // 그 외 요청들은 로그인해야만..
        );


        http.formLogin((auth) -> auth.loginPage("/login")   // login페이지 URL 지정.  @RequestMapping("/login")을 만들어야한다.  => login.html
            .loginProcessingUrl("/loginProc")   // login.html에서  form태그의 action URL이  /loginProc여야한다.
                                                // @RequestMapping("/loginProc")는 없다. login과정은 security가 하기때문.
            .defaultSuccessUrl("/")             // 로그인 성공 후 redirect 되는 URL
            .permitAll()
        );

        http.logout((auth) -> auth.logoutUrl("/logout")   //   /logout으로 요청하면 logout이 된다.  @RM은 없다. 로그아웃도 security가 한다.
            .logoutSuccessUrl("/"));                     //    로그아웃 성공 후 /로 redirect


        http.csrf((auth) -> auth.disable());   //보안관련설정. 자세한 설명은 csrf 따로.
        return http.build();
    }
}

 

 

여기에 DB에 저장될 UserEntity객체를 만들고  회원가입을 진행해보자.

회원가입 자체는 Spring security와 상관없고,

단지   /join/**   에 대한 요청이 permitAll()이기때문에

회원가입은 로그인 없이 동작한다. 

 

 

 

회원가입  기능

UserEntity

@Entity
@Getter
@Setter
public class UserEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;   //JPA 기본 ID Long 



    @Column(unique = true)
    private String username;   //spring이 entity의 필드랑 파라미터를 비교하는건 아님.   security에서 username이 기본이지만, 사용자입장에선 ID
    private String password;  //spring이  entity의 필드랑 파라미터를 비교하는건 아님


    //private String name;   //진짜 유저 이름. 홍길동


    private List<String> roles=new ArrayList<>();
    //권한은 기본적으로 여러개입니다. 많은 곳에서 권한을 간단히 하려고 String 1개만 하는 경우가 대부분이지만
    // Security도  권한 여러개를 기본으로 제공하기 때문에 여러개인게 더 편함.


}

 

 

UserRepository

public interface UserRepository extends JpaRepository<UserEntity, Long> {
    public   UserEntity findByUsername(String username);    //join하는데는 필요없지만, 나중에 로그인할 때 쓰려고 미리만듦.
}

 

 

 

JoinDTO

@Setter
@Getter
public class JoinDTO {
    private String username;
    private String password;
}

 

 

 

 

JoinServie

@Service
public class JoinService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    public void joinProcess(JoinDTO joinDTO) {
        //db에 이미 동일한 username을 가진 회원이 존재하는지?
        UserEntity find = userRepository.findByUsername(joinDTO.getUsername());
        if(find!=null) {
            System.out.println("이미 있는 ID입니다.");
            return ;
        }
        UserEntity user = new UserEntity();
        user.setUsername(joinDTO.getUsername());
        user.setPassword(passwordEncoder.encode(joinDTO.getPassword()));  //DB에 저장될 때는 반드시 encoding되서 저장되어야한다.
        user.getRoles().add("USER");     //hasAuthority("USER") 에 맞게 USER로 세팅

        userRepository.save(user);
    }
}

 

 

 

 

JoinController

@Controller
@RequestMapping("/join")
@RequiredArgsConstructor
public class JoinController {

    private  final JoinService joinService;

    @GetMapping("/join")
    public  String join(){
        return "join";
    }

    @ResponseBody
    @PostMapping("/join")
    public  String joinPost(JoinDTO joinDTO){
        joinService.joinProcess(joinDTO);
        return "회원가입 완료!";
    }
}

 

 

 

join.hml

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>


회원가입 페이지입니다 <br> <br>


<form action="/join/join" method="post" name="joinForm">
    <input type="text" name="username" placeholder="psername"/>
    <input type="password" name="password" placeholder="password"/>
    <input type="submit" value="join"/>
</form>



</body>
</html>

 

 

 

 

회원가입 실행

회원가입 진행

url은 /join/join

 

 

 

회원가입 후 DB