인프런 스프링부트 시큐리티 & JWT 강의를 수강하며 작성하는 내용입니다.
@Configuration
@EnableWebSecurity // 스프링 시큐리티 필터가 스프링 필터체인에 등록됨
class SecurityConfig {
// @Bean: 해당 메서드의 리턴되는 오브젝트를 IoC로 등록해준다
@Bean
fun encodePwd(): BCryptPasswordEncoder {
return BCryptPasswordEncoder()
}
@Bean
@Throws(Exception::class)
fun filterChain(http: HttpSecurity): SecurityFilterChain? {
http
.authorizeRequests { authz ->
authz
.antMatchers("/user/**").authenticated()
.antMatchers("/manager/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_MANAGER')")
.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
.anyRequest().permitAll()
.and()
.formLogin()
.loginPage("/login")
}
.httpBasic(withDefaults())
.cors().and() // 없으면 join 을 타지 않아 추가함
.csrf().disable()
return http.build()
}
@Entity
class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Int? = null
var username: String? = null
var password: String? = null
var email: String? = null
var role: String? = null
@CreationTimestamp
val createDate: Timestamp? = null
}
interface UserRepository : JpaRepository<User, Int> {}
@Controller // view를 리턴하겠다
class IndexController(
private val userRepository: UserRepository,
private val bCryptPasswordEncoder: BCryptPasswordEncoder
) {
// localhost:8080
@GetMapping("/")
fun index(): String {
// 머스테치 기본폴더 src/main/resources/
// view resolver 설정: templates (prefix), .mustache (suffix) 생략가능
return "index" // src/main/resources/templates/index.mustache
}
@ResponseBody
@GetMapping("/user")
fun user(): String {
return "user"
}
@ResponseBody
@GetMapping("/admin")
fun admin(): String {
return "admin"
}
@ResponseBody
@GetMapping("/manager")
fun manager(): String {
return "manager"
}
@GetMapping("/loginForm")
fun loginForm(): String {
return "loginForm"
}
@PostMapping("/join")
fun join(user: User): String {
println("${user.username} / ${user.email}")
user.role = "ROLE_USER"
val rawPassword = user.password
val encPassword = bCryptPasswordEncoder.encode(rawPassword)
user.password = encPassword
userRepository.save(user)
return "redirect:/loginForm"
}
@GetMapping("/joinForm")
fun joinForm(): String {
return "joinForm"
}
@ResponseBody
@GetMapping("/joinProc")
fun joinProc(): String {
return "회원가입 완료됨"
}
}
loginForm
<!DOCTYPE html>
<html lang="en">
<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 lang="en">
<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>
로그인 없이 실행해보면
http://localhost:8080/user -> http://localhost:8080/login
http://localhost:8080/admin -> http://localhost:8080/login
http://localhost:8080/manager -> http://localhost:8080/login
role이 없기 때문에 login 화면으로 이동하는 것을 확인할 수 있고
회원가입 페이지에 데이터 입력 후 버튼을 누르면
user 데이터와 암호화된 비밀번호가 db에 잘 들어간 것을 확인할 수 있다