https://www.youtube.com/watch?v=NPRh2v7PTZg&list=PLJkjrxxiBSFCcOjy0AAVGNtIa08VLk1EJ
개발자 유미님의 스프링부트 JWT 시큐리티
위 영상을 보고 만들예정이다. 이번 내용은 영상 1~4편까지의 내용이다.
버전 및 의존성
- Spring Boot 3.2.1
- Security 6.2.1
- Lombok
- Spring Data JPA - MySQL
- Gradle - Groovy
- IntelliJ Ultimate
전체적인 내용
스프링 시큐리티 6 프레임워크를 사용할 것이다. JWT 기반의 인증/인가를 구현하고 회원 정보 저장(영속성) MySQL 데이터베이스를 활용한다.
서버는 API 서버 형태로 구축한다. (웹 페이지를 응답하는 것이 아닌 API 클라이언트 요청을 통해 데이터 응답만 확인함)
회원가입 흐름
POST요청으로 /join으로 form data형식으로 요청한다 그 떄 DTO를 사용하여 데이터들이 JoinController에 전달되게 되고 Controller에서 DTO를 사용하여 JoinService로 가게된다 Service에서 UserEntity를 참조하고 UserEntity에서 UserRepository를 사용해서 Repository는 Spring app의 UserEntity와 DB의 UserEntity를 연결해준다 그렇게 POST방식으로 전달된 데이터들을 DB에 저장한다.
로그인(인증) 흐름
세션방식과 JWT토큰 방식이 다른 점은 세션방식은 서버 세션이 유저 정보를 저장하지만 JWT토큰 방식은 토큰에 담아서 응답한다.
JWTUtil에서 JWT 토큰을 create한다 토큰 내에는 여러가지 정보가 포함되어있다(username, role, isexpired 를 get할 수 있다)
그리고 Spring Security에 포함되어있는 Authentication Manager, UsernamePasswordAuthrnticationFiler를 사용해서
토큰을 발행한다. (이 정보도 JWTUtil로 간다.) 토큰이 헤더에 포함되어서 요청이 되어야만 인가된 사용자로 인식한다.
경로 접근(인가) 동작은 JWTFilter에서 헤더의 JWT를 찾아 검증을 하고 일시적 요청에 대한 Session을 생성하게 된다. (생성된 세션은 요청이 끝나면 소멸된다)
깃허브 커밋 로그
발생한 오류
이 부분이 나의 마리갤 백엔드를 구현하면서 블로그에 올리는 이유 중 가장 큰 이유가 될 것이고 가장 중요한 부분이 될 것이다. 스스로 오류를 해결해보면서 가슴이 찌릿하는 경험을 기록할 것이다.
1~4편을 진행하며 발생했던 오류는 거의 없었다. 그냥 영상보고 따라만 하면 되는 내용들이었다.
하지만 마지막에 postman을 사용하여 get요청을 보내보는데 아무리해도 401오류가 나왔다 그래서 오타인가? 싶어서 그대로 복사를 해보니까 잘 동작했다 그래서 어느 부분이 틀린거지? 하고 찾아보던 중
http
.authorizeHttpRequests((auth) -> auth
.requestMatchers("/login", "/", "join").permitAll()
.requestMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated());
// SecurityConfig
저기서 .requestMatchers부분을 빼먹었던 것이다.
특정 경로로의 get요청을 허락해줘야하는데 나는 거부를 했던 것이다 그래서 401오류가 뜬 것이다.
400번대 오류는 클라이언트 요청오류라 나의 잘못이고
500번대 오류는 서버 오류라 서버의 잘못이다.
200은 성공! OK!
400번대 중에서도 자주 볼 수 있는 내용이 400, 401, 403, 404가 될 것이다.
400: bad request - 클라이언트의 잘못된 요청 ex) 요청구문 오류. / 오타 확인하기
401: Unauthorized - Authentication되지 않음 ex) 클라이언트 인증 되지 않음. / ID/PW가 틀림
403: Forbidden - 인증 자격은 있지만 접근 권한이 없다 ex) 특정 role은 접근할 수 없다. / 보안구역 접근, 접근권한 확인 user가 admin page를 접근한다던가.
404: Not Found - 요청 리소스가 서버에 없음 ex) 찾는 내용이 없다. / 롯데리아가서 빅맥 주문하기
503: Service Unavailable - 서비스 이용불가 ex) 서버상태가 이상하다. / 일시적인 과부하 혹은 서버 상태 불량
이런 오류가 존재하더라 HTTP에는 postman도 써보는 계기가 되었다.