[이상형 월드컵 프로젝트 사용 기술] 시큐리티 로그인, 로그아웃 설정

KangHo Lee's avatar
Dec 30, 2024
[이상형 월드컵 프로젝트 사용 기술] 시큐리티 로그인, 로그아웃 설정

시큐리티 설정 파일

SecurityConfig
@RequiredArgsConstructor @Configuration public class SecurityConfig { @Bean public PasswordEncoder passwordEncoder() { // 패스워드 암호화 방식 지정 return new BCryptPasswordEncoder(); } private final LoginLogService loginLogService; @Bean public SecurityFilterChain configure(HttpSecurity http) throws Exception { http.headers(httpSecurityHeadersConfigurer -> httpSecurityHeadersConfigurer.frameOptions(frameOptionsConfig -> frameOptionsConfig.sameOrigin())) // CSRF 보호를 비활성화합니다. .csrf(c -> c.disable()) // 요청 인증 설정 .authorizeHttpRequests(r -> r.requestMatchers("/s/**") // s로 시작하는 모든 요청은 인증 필요 .authenticated() .anyRequest() .permitAll()) // 로그인 설정 .formLogin(f -> f.loginPage("/login-form") .loginProcessingUrl("/login") .successHandler((request, response, authentication) -> { User user = (User) authentication.getPrincipal(); HttpSession session = request.getSession(); session.setAttribute("sessionUser", user); String userAgent = request.getHeader("User-Agent"); loginLogService.save(user, userAgent); response.sendRedirect("/main"); })) // 로그아웃 설정 .logout(l -> l.logoutUrl("/logout") .logoutSuccessUrl("/main") .invalidateHttpSession(true) .deleteCookies("JSESSIONID") ); return http.build(); } }

로그인 설정

.formLogin(f -> f.loginPage("/login-form") .loginProcessingUrl("/login") .successHandler((request, response, authentication) -> { User user = (User) authentication.getPrincipal(); HttpSession session = request.getSession(); session.setAttribute("sessionUser", user); String userAgent = request.getHeader("User-Agent"); loginLogService.save(user, userAgent); response.sendRedirect("/main");
위 설정이 자동으로 구현해주는 로그인 메서드
@PostMapping("/login") public String login(User user) { session.setAttribute("sessionUser", user); return "redirect:/main"; }
  • session 에 저장된 sessionUser 정보는 Controller에서 @AuthenticationPrincipal 어노테이션으로 가져올 수 있습니다.
@Controller public class UserController { @GetMapping("/profile") public String getUserProfile(@AuthenticationPrincipal User user, Model model) { model.addAttribute("user", user); return "profile"; } }

로그아웃 설정

.logout(l -> l.logoutUrl("/logout") .logoutSuccessUrl("/main") .invalidateHttpSession(true) .deleteCookies("JSESSIONID"));
위 설정이 자동으로 구현해주는 로그아웃 메서드
@PostMapping("/logout") public String logout(HttpServletRequest request) { HttpSession session = request.getSession(); if (session != null) { session.invalidate(); // 세션 무효화 } // 쿠키 삭제 javax.servlet.http.Cookie cookie = new javax.servlet.http.Cookie("JSESSIONID", null); cookie.setPath("/"); cookie.setMaxAge(0); response.addCookie(cookie); return "redirect:/main"; }

User (회원) 엔티티

@NoArgsConstructor @Getter @Table(name = "user_tb") @Entity public class User implements UserDetails { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; // email을 username으로 사용 @Column(unique = true, nullable = false) private String email; @Column(nullable = false) private String password; // username 대신 email을 반환 @Override public String getUsername() { return email; } @Override public String getPassword() { return password; } // 권한 확인(role -> admin, manager, guest 같은) @Override public Collection<? extends GrantedAuthority> getAuthorities() { return List.of(); } // 계정이 만료되지 않았는지 확인합니다. @Override public boolean isAccountNonExpired() { return true; } // ID 잠금 여부를 확인합니다. @Override public boolean isAccountNonLocked() { return true; } // 비밀번호가 만료되지 않았는지 확인합니다. @Override public boolean isCredentialsNonExpired() { return true; } // 계정 비활성화 여부를 확인합니다. @Override public boolean isEnabled() { return true; } }
  • 스프링이 검증할 회원 엔티티는 implements UserDetails 이 필요합니다.
  • Spring Security는 기본적으로 username과 password를 체크할 수 있도록 설정됩니다.
  • 비밀번호 비교가 제대로 작동하려면 비밀번호를 해시화해서 저장해야 합니다.
// username 대신 email을 반환 @Override public String getUsername() { return email; }
  • username 대신 email 비교를 하고 싶다면 getter을 Override합니다.
 
 
 
 
 
 
 
 
 
 
 
 


 
Share article

devleekangho