<!-- .css 연결 (css 폴더의 style.css 파일 연결) -->
<link rel="stylesheet" type="text/css" href="/css/style.css">
<!-- .js 연결 (basic.js 파일 연결) -->
<script src="basic.js"></script>
// 스프링 시큐리티 추가
implementation 'org.springframework.boot:spring-boot-starter-security'
@Configuration // 스프링(서버)이 기동되는 순간에 설정을 한다는 의미
@EnableWebSecurity // 스프링 Security 지원을 가능하게 함
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override // 부모 클래스의 기본설정을 변경하기 위해 사용
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// 어떤 요청이든 '인증' => 예외 설정을 안하면 로그인 부터 해야함
.anyRequest().authenticated()
.and() // 조건 추가
// 로그인 기능 허용
.formLogin()
.defaultSuccessUrl("/") // 성공하면 루트('/')로 이동
.permitAll()
.and()
// 로그아웃 기능 허용
.logout()
.permitAll();
}
}
.and()
// 로그인 기능 허용
.formLogin()
.loginPage("/user/login") // 로그인 View 제공 (Get 요청 URL /user/login)
.defaultSuccessUrl("/") // 로그인 처리 후 성공 시 URL
.failureUrl("/user/login?error") // 로그인 처리 후 실패 시 URL
.permitAll()
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class UserController {
// 회원 로그인 페이지
@GetMapping("/user/login")
public String login() {
return "login";
}
// 회원 가입 페이지
@GetMapping("/user/signup")
public String signup() {
return "signup";
}
}
// image 폴더를 login 없이 허용
.antMatchers("/images/**").permitAll()
// css 폴더를 login 없이 허용
.antMatchers("/css/**").permitAll()
.antMatchers("/user/**").permitAll()
http.csrf()
.ignoringAntMatchers("/user/**");
http.csrf()
.ignoringAntMatchers("/user/**");
@Bean
public BCryptPasswordEncoder encodePassword() {
return new BCryptPasswordEncoder();
}
public void registerUser(SignupRequestDto requestDto) {
// 회원 ID 중복 확인
String username = requestDto.getUsername();
Optional<User> found = userRepository.findByUsername(username);
if (found.isPresent()) {
throw new IllegalArgumentException("중복된 사용자 ID 가 존재합니다.");
}
// 패스워드 암호화
String password = passwordEncoder.encode(requestDto.getPassword());
String email = requestDto.getEmail();
// 사용자 ROLE 확인
UserRoleEnum role = UserRoleEnum.USER;
if (requestDto.isAdmin()) {
if (!requestDto.getAdminToken().equals(ADMIN_TOKEN)) {
throw new IllegalArgumentException("관리자 암호가 틀려 등록이 불가능합니다.");
}
role = UserRoleEnum.ADMIN;
}
User user = new User(username, password, email, role);
userRepository.save(user);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
// [로그인 기능]
.formLogin()
// 로그인 처리 (POST /user/login)
.loginProcessingUrl("/user/login")
.permitAll();
}
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("Can't find " + username));
UserDetails userDetails = new UserDetailsImpl(user)
"인증 관리자" 가 인증 처리
1) 아래 2 개의 username, password 일치 여부 확인
2) password 비교 시
3) 인증 성공 시 → 세션에 로그인 정보 저장
4) 인증 실패 시 → Error 발생
로그아웃 처리 과정
로그인된 회원 정보 사용 가능
@Controller
public class HomeController {
@GetMapping("/")
public String home(Model model, @AuthenticationPrincipal UserDetailsImpl userDetails) {
model.addAttribute("username", userDetails.getUsername());
return "index";
}
}
// Thymeleaf (뷰 템플릿 엔진)
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'