-
Delivery Together - JWT 인증방식의 로그인(4)Projects/Problem & Solution 2021. 12. 26. 20:33
개요
이전 게시물에서 사용자 로그인 정보를 통해 JWT를 발급하는 과정까지 알아보았다. 이번에는 발급한 JWT를 통해 어떠한 방식으로 정보 교류가 이루어지는지 알아보도록 하겠다.
JWT 인증
JwtAuthenticationFilter 클래스
public class JwtAuthenticationFilter extends OncePerRequestFilter { private UserDetailsService userDetailsService; private JwtTokenHelper jwtTokenHelper; public JwtAuthenticationFilter(UserDetailsService userDetailsService, JwtTokenHelper jwtTokenHelper) { this.userDetailsService = userDetailsService; this.jwtTokenHelper = jwtTokenHelper; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String authToken = jwtTokenHelper.getToken(request); // 클라이언트 요청에 대한 JWT /* 토큰 정보가 존재하는 경우 */ if (authToken != null) { String username = jwtTokenHelper.getUsernameFromToken(authToken); /* 토큰의 username이 존재하는 경우 */ if (username != null) { UserDetails userDetails = userDetailsService.loadUserByUsername(username); /* 토큰이 유효한 경우 */ if (jwtTokenHelper.isTokenValidate(authToken, userDetails)) { UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); SecurityContextHolder.getContext().setAuthentication(authentication); } } } filterChain.doFilter(request, response); } }
ㆍ 위 클래스는 JWT를 이용해서 클라이언트 인증을 수행하는 클래스이다. 즉, 토큰의 유형성을 검사하는 클래스이다.
ㆍ JwtAuthenticationFilter 클래스는 OncePerRequestFilter 클래스를 상속받는 형태로 구성되어 있다.
ㆍ 우선, JWT의 유효성을 검사한 후 유효한 토큰으로 판명된 경우 토큰으로부터 얻은 UserDetails 객체와 권한 정보를 이용해서 UsernamePasswordAuthenticationToken 객체를 생성한다.
ㆍ 생성된 UsernamePasswordAuthenticationToken 객체를 SecurityContextHolder.getContext().setAuthentication() 메서드를 통해서 SecurityContextHolder에 집어넣음으로써 인증이 완료된다.
OncePerRequestFilter란?
OncePerRequestFilter는 이름에서도 알 수 있듯이 모든 서블릿에 일관된 요청을 처리하기 위해 만들어진 필터이다. 이 추상 클래스를 구현한 필터는 사용자의 한번에 요청 당 딱 한 번만실행되는 필터를 만들 수 있다.
UsernamePasswordAuthenticationToken
UsernamePasswordAuthenticationToken 클래스는 Authentication 인터페이스를 구현한 클래스로, 사용자의 인증이 완료된 후 최종적으로 Spring Security에게 전달해주는 구현체이다.
사용자 정보 받기
컨트롤러 생성
@GetMapping("/auth/userinfo") public ResponseEntity<?> getUserInfo(Principal user) throws Exception { User userEntity = (User) userServiceImpl.loadUserByUsername(user.getName()); UserInfo userInfo = new UserInfo(); userInfo.setUsername(userEntity.getUsername()); userInfo.setBirthdate(userEntity.getBirthdate()); userInfo.setCountry(userEntity.getCountry()); userInfo.setGender(userEntity.getGender()); return new ResponseEntity<>(userInfo, HttpStatus.OK); }
ㆍ 로그인을 성공적으로 수행한 사용자가 자신의 프로필 페이지에 필요한 정보를 받기 위한 메서드이다.
ㆍ 로그인이 완료되면서 발급받은 JWT를 Header를 통해서 서버 측으로 전송한다.
ㆍ 서버 측에서는 JwtAuthenticationFilter 클래스를 통해 JWT의 유효성을 검사하고, 검사가 완료되면 JWT로부터 생성된 Authentication 객체를 SecurityContextHolder에 집어넣는다.
ㆍ SecurityContextHolder안에 Authentication 객체는 Principal을 포함하고 있기 때문에, 컨트롤러에서도 접근이 가능하다.
테스트
1. 로그인 요청
ㆍ 사용자가 로그인을 수행하기 위해 username과 password를 서버 측으로 요청한다.
2. JWT 발급
ㆍ 로그인이 성공적으로 완료가 되면, 서버 측에서 사용자 정보를 통해 만들어진 JWT를 발급한다.
3. 사용자 정보 요청
ㆍ 로그인 사용자의 정보를 요청하기 위해 발급받은 JWT를 Header에 포함하여 컨트롤러의 주소로 전송한다.
ㆍ JWT 검증이 완료되면 로그인 사용자에 대한 정보가 올바르게 응답되는 것을 확인할 수 있다.
GitHub - yu-capstone-design/delivery-together: 🍕 배달 주문을 같이할 사용자를 찾도록 매칭 서비스를 제공
🍕 배달 주문을 같이할 사용자를 찾도록 매칭 서비스를 제공해주는 애플리케이션. Contribute to yu-capstone-design/delivery-together development by creating an account on GitHub.
github.com
728x90'Projects > Problem & Solution' 카테고리의 다른 글
Sneakers Mania - 카카오 로그인(2) (0) 2021.12.27 Sneakers Mania - 카카오 로그인(1) (0) 2021.12.27 Delivery Together - JWT 인증방식의 로그인(3) (0) 2021.12.25 Delivery Together - JWT 인증방식의 로그인(2) (0) 2021.12.24 Delivery Together - JWT 인증방식의 로그인(1) (0) 2021.12.23