SpringBoot 프로젝트에서 Spring Securtiy와 카카오API를 활용하여 카카오 로그인을 구현했는데 페이지에서 CSS, JavaScript 같은 정적 파일이 적용이 안 된다.
알아보니까 Spring Securtiy에서 .antMarchers를 이용하여 해당 경로는 인증 없이 접근을 허용하는 코드를 추가했었는데 정적 파일도 추가로 적어줘야 페이지 로딩시 CSS, JavaScript를 불러올 수 있다고 한다.
기존 코드
@Configuration // 해당 클래스를 스프링 설정 클래스로 등록
@EnableWebSecurity // spring security 설정을 활성화
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired // 해당 타입의 빈을 자동으로 주입
private CustomOAuth2UserService customOAuth2UserService;
@Override // 상위 클래스의 메소드를 오버라이드
protected void configure(HttpSecurity http) throws Exception {
http
// 카카오 로그인
.authorizeRequests() // HttpServletRequest에 따라 접근을 제한하거나 허용하려면 사용
.antMatchers("/", "/user/**", "/search_fail", "/게시판").permitAll() // 해당 경로에 대한 모든 요청을 허용
.anyRequest().authenticated() // 그 외의 모든 요청은 인증이 필요
.and()
.oauth2Login() // OAuth 2 로그인 기능 활성화
.userInfoEndpoint() // OAuth2 로그인 성공 이후 사용자 정보를 가져올 때 설정을 저장
.userService(customOAuth2UserService) // OAuth 2 사용자 정보를 얻기 위한 서비스 지정
.and()
.defaultSuccessUrl("/") // 로그인 성공 시 리다이렉트할 URL
.failureUrl("/login?error=true") // 로그인 실패 시 리다이렉트할 URL
.and()
.csrf().ignoringAntMatchers("/", "/user/**", "/search_fail", "/게시판") // CSRF 보호에서 제외 페이지
.and()
.headers().frameOptions().disable() // X-Frame-Options 헤더를 비활성화하여 iframe 내에서 페이지를 렌더링 허용
.and()
// 카카오 로그아웃
.logout()
.logoutUrl("/user/logout") // 로그아웃을 수행하는 URL
.logoutSuccessUrl("/") // 로그아웃 성공 후 리다이렉트할 URL
.invalidateHttpSession(true) // 세션 무효화
.addLogoutHandler((request, response, authentication) -> { // 소셜 로그아웃 처리 및 세션 관련 작업 등 추가
HttpSession session = request.getSession(); // 세션을 무효화하여 사용자의 세션 정보를 제거
session.invalidate();
})
.logoutSuccessHandler((request, response, authentication) -> response.sendRedirect("/user/login")) // 소셜 로그아웃 성공 후 처리 및 리다이렉트3
.deleteCookies("remember-me"); // 로그아웃 시 제거할 쿠키를 설정
}
}
변경 코드
@Configuration // 해당 클래스를 스프링 설정 클래스로 등록
@EnableWebSecurity // spring security 설정을 활성화
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired // 해당 타입의 빈을 자동으로 주입
private CustomOAuth2UserService customOAuth2UserService;
@Override // 상위 클래스의 메소드를 오버라이드
protected void configure(HttpSecurity http) throws Exception {
http
// 카카오 로그인
.authorizeRequests() // HttpServletRequest에 따라 접근을 제한하거나 허용하려면 사용
.antMatchers("/", "/user/**", "/search_fail", "/게시판").permitAll() // 해당 경로에 대한 모든 요청을 허용
.antMatchers( "/static1/**", "/static2/**").permitAll() // 정적 자원에 대한 접근 허용
.anyRequest().authenticated() // 그 외의 모든 요청은 인증이 필요
.and()
.oauth2Login() // OAuth 2 로그인 기능 활성화
.userInfoEndpoint() // OAuth2 로그인 성공 이후 사용자 정보를 가져올 때 설정을 저장
.userService(customOAuth2UserService) // OAuth 2 사용자 정보를 얻기 위한 서비스 지정
.and()
.defaultSuccessUrl("/") // 로그인 성공 시 리다이렉트할 URL
.failureUrl("/login?error=true") // 로그인 실패 시 리다이렉트할 URL
.and()
.csrf().ignoringAntMatchers("/", "/user/**", "/search_fail", "/게시판") // CSRF 보호에서 제외 페이지
.and()
.headers().frameOptions().disable() // X-Frame-Options 헤더를 비활성화하여 iframe 내에서 페이지를 렌더링 허용
.and()
// 카카오 로그아웃
.logout()
.logoutUrl("/user/logout") // 로그아웃을 수행하는 URL
.logoutSuccessUrl("/") // 로그아웃 성공 후 리다이렉트할 URL
.invalidateHttpSession(true) // 세션 무효화
.addLogoutHandler((request, response, authentication) -> { // 소셜 로그아웃 처리 및 세션 관련 작업 등 추가
HttpSession session = request.getSession(); // 세션을 무효화하여 사용자의 세션 정보를 제거
session.invalidate();
})
.logoutSuccessHandler((request, response, authentication) -> response.sendRedirect("/user/login")) // 소셜 로그아웃 성공 후 처리 및 리다이렉트3
.deleteCookies("remember-me"); // 로그아웃 시 제거할 쿠키를 설정
}
}
보통은 .antMatchers("/css/**", "/js/**", "/images/**").permitAll()
이렇게 쓰는 거 같지만 나의 경우엔 부트스트랩을 두 개 쓰고 있어서
src/
└── main/
└── resources/
└── static/
├── static1/
│ ├── css/
│ │ └── bootstrap.min.css
│ ├── js/
│ │ └── bootstrap.min.js
│ └── ...
├── static2/
│ ├── css/
│ │ └── bootstrap.min.css
│ ├── js/
│ │ └── bootstrap.min.js
│ └── ...
└── templates/
├── index.html/
├── login.html/
└── ...
(static1 = 부트스트랩1, static2 = 부트스트랩2)
파일 구조가 이렇게 되어있었다.
그래서 .antMatchers( "/static1/**", "/static2/**").permitAll()
이렇게 추가했더니 모든 페이지에서 정상적으로 적용됐다!