튜토리얼 코드

https://github.com/SilverNine/spring-boot-jwt-tutorial

바로가기

Spring Boot JWT Tutorial (1) – JWT 소개, 프로젝트 생성

Spring Boot JWT Tutorial (2) – Security 기본 설정, Data 설정

Spring Boot JWT Tutorial (3) – JWT 코드, Security 설정 추가

Spring Boot JWT Tutorial (4) – Repository, 로그인

Spring Boot JWT Tutorial (5) – 회원가입, 권한검증

DTO

dto 패키지를 만들고 외부와의 데이터 통신에 사용할 3개의 클래스를 만들어 줍니다.

LoginDto.java

TokenDto.java

UserDto.java

로그인

UserRepository.java

이전에 만들었던 User Entity에 매핑되는 Repository를 만들기 위해 repository 패키지를 생성하고 UserRepository 인터페이스를 추가합니다.

JPA 관련해서는 추후 기회가 되면 따로 자세히 다루도록 하겠습니다. 여기서는 간단하게만 짚고 넘어가겠습니다.

JpaRepository를 extends하는 것으로 save(), findOne(), findAll() 등의 메소드를 기본적으로 사용할 수 있게 됩니다.

findOneWithAuthoritiesByUsername 메소드는 username을 기준으로 User 정보 ( authorities 정보 포함 ) 를 가져오는 역할을 수행합니다. @EntityGraph(attributePaths) 어노테이션은 해당 쿼리가 수행될때 Lazy 조회가 아닌 Eager 조회로 authorities 정보를 조인해서 가져오게 됩니다.

CustomUserDetailsService.java

UserDetailsService를 implements하고 위에서 만들었던 UserRepository를 주입받는 CustomUserDetailsService 클래스를 생성합니다.

로그인 시 authenticate 메소드를 수행할때 Database에서 User 정보를 조회해오는 loadUserByUsername 메소드가 실행됩니다.

우리는 loadUserByUsername 메소드를 오버라이드해서 Database에서 User 정보를 권한 정보와 함께 가져오는 로직을 구현했습니다.

람다식을 이용해 Database에서 조회해온 User 및 권한 정보를 org.springframework.security.core.userdetails.User 객체로 변환하여 리턴합니다.

AuthController.java

TokenProvider, AuthenticationManagerBuilder 를 주입받는 AuthController 클래스를 만들겠습니다.

/api/authenticate 요청을 처리하는 authorize 메소드는

username, password를 파라미터로 받아서 UsernamePasswordAuthenticationToken 객체를 생성합니다.

해당 객체를 통해 authenticate 메소드 로직을 수행합니다. 이때 위에서 만들었던 loadUserByUsername 메소드가 수행되며 유저 정보를 조회해서 인증 정보를 생성하게 됩니다.

해당 인증 정보를 JwtFilter 클래스의 doFilter 메소드와 유사하게 현재 실행중인 스레드 ( Security Context ) 에 저장합니다.

또한 해당 인증 정보를 기반으로 TokenProvider의 createToken 메소드를 통해 jwt 토큰을 생성합니다.

생성된 Token을 Response Header에 넣고, TokenDto 객체를 이용해 Reponse Body에도 넣어서 리턴합니다.

로그인 테스트

포스트맨을 통해 http://localhost:8080/api/authenticate 를 POST로 호출합니다.

Request Body에는 로그인을 위한 username, password을 넣어줍니다.

admin 유저는 이전에 만들었던 data.sql을 통해 자동으로 Database에 저장된 유저 입니다.

호출해보면 정상적으로 응답을 받았고 Response Body에 token이 들어있는 것을 볼 수 있습니다.

Response Body의 헤더에도 정상적으로 생성된 토큰이 들어있는 것을 볼 수 있습니다.

여기서 편리한 기능이 있는데요. Tests 탭에서 아래와 같이 코딩을 해주면 Postman 전역 변수에 해당 토큰을 담아서 다른 호출 작업에서 이 값을 이용할 수 있습니다.

다음 편에서는 회원가입과 테스트 API를 만들어서 권한 검증을 할 수 있도록 구성하겠습니다.