1. 문제
Spring Security 적용 후, Postman으로 회원가입을 완료했지만 다른 페이지로 접근이 되지 않는다.
*Spring Security 설정은 책 '스프링 부트3 백엔드 개발자되기' 를 참고해서 설정
깃 주소 : https://github.com/shinsunyoung/springboot-developer
'/api/signup' 회원 가입은 되는 것을 확인 했다.
회원 가입 후 '/api/test' 다른 url로 변경하고 send버튼을 눌러 request를 요청했다. -> 당연히 백엔드 컨트롤러가 작성되어 있어야 한다.
'api/test' url을 요청 했을 때 'Probably stuck in redirect loop http://localhost:8080/login' 에러가 발생한다.
2. 문제 원인
'Error: Exceeded maxRedirects. Probably stuck in a redirect loop http://localhost:8080/login'의 내용은 Spring Security가 인증되지 않은 요청을 처리할 때 발생한다. 스프링 시큐리티는 기본적으로 인증되지 않은 사용자는 login 페이지로 redirect 한다.
Spring Security를 처음 실행했을 때 작성하지 않은 위 그림에 나온 'Please sign in' 페이지가 자동으로 표시되는 것을 확인할 수 있다. 이 페이지는 Spring Security에 기본적으로 생성되어 있는 페이지이다. 여기서 해당 페이지의 기본 설정에 따라 url은 '/login'이다. 따라서 Postman에서 요청을 보낼 때, 'http://localhost:8080/login'으로로 지속적으로 리디렉션되어 'Exceeded maxRedirects' 오류가 발생한다. 인증되지 않은 요청 처리는 로그인 하지 않았다는 말이다.
문제를 정리해보면 다음과 같다.
- 'http://localhost:8080/api/signup'에서 내가 만든 회원가입 API를 통해 ID와 비밀번호가 DB에 저장된다.
- 회원가입이 완료되면, 로그인된 상태인지 궁금해진다.
- 이를 확인하기 위해 'http://localhost:8080/api/test'에 접근해본다.
- 그러나 로그인이 되어 있지 않으므로 'http://localhost:8080/login'으로 무한 리디렉션이 발생한다.
3. 해결 방법
@RequiredArgsConstructor
@Controller
public class MemberApiController {
private final MemberService userService;
// 회원가입
@PostMapping("/api/signup")
public ResponseEntity signup(@RequestBody MemberDTO memberDTO) {
Long num = userService.save(memberDTO);
return ResponseEntity.ok()
.body(num);
}
@GetMapping("/api/test")
public ResponseEntity test() {
return ResponseEntity.ok().body("Hello World");
}
}
회원가입 하는 controller는 위와같다.
public class WebSecurityConfig {
private final MemberDetailService userDetailService;
@Bean
public WebSecurityCustomizer configure() {
// 중간 생략...
http
.httpBasic(withDefaults());
return http.build();
}
}
* Spring Boot 3.1.X 이상, Spring Security 6.X.X 이상입니다. 이전 버전은 .and( ) 사용해서 추가해야합니다.
WebSecurityConfig 설정 파일을 만들었을 텐데 httpBasic(withDefaults())를 활성화 한다. httpBasic 인증 방식은 ' 아이디와 비밀번호를 Base64 방식으로 인코딩한 뒤 HTTP 인증 헤더에 부착하여 서버측으로 요청을 보내는 방식이다.' 라고한다.
참조 페이지 : https://www.devyummi.com/page?id=668bf713f60758f5af9a30f3
Spring Security 아무것도 안하고 처음에 켰을 때 로그인 하는 방식이다. 위에서 'Please sign in'으로 로그인하는 방식이 httpBasic 이다.
그 다음 Postman으로 들어가서 Auth -> Auth Type을 Basic Auth로 설정하고 회원 가입에 사용했던 id와 비밀번호를 넣는다.
요청이 성공했다.
위 말고도 살짝 야매 방식이 있는데
public class WebSecurityConfig {
private final MemberDetailService userDetailService;
@Bean
public WebSecurityCustomizer configure() {
// 중간 생략...
http
.authorizeHttpRequests(authorize -> authorize
// 중간 생략
.anyRequest().permitAll()
);
return http.build();
}
}
모든 어떤 권한에 대해서도 permitAll( )을 하면 된다. 그러면 사실상 시큐리티를 사용하지 않는 것과 같다.
[결론] : Spring Security가 어떻게 동작하는지 더 공부하고, postman에서 세션 설정하는 방법이 있는데 알아봐야 겠다.