본문 바로가기
🍃 𝗦𝗽𝗿𝗶𝗻𝗴 𝗕𝗼𝗼𝘁

스프링부트 JWT 인증 과정

by 비타민찌 2022. 3. 18.
728x90

프로젝트를 진행하면서 전에 올렸던 'JWT 인증 과정' 포스팅에 별로인 코드가 있는 것을 알았다

로그인 과정에서 불필요하게 디비 접속을 한번 더 하더라..🤔

그래서 문제점과 해결 방법에 대해 적어본다.

 

 

<컨트롤러 코드>

 @PostMapping(value = "/login")
    public ResponseEntity<?> createAuthenticationToken(@RequestBody UserLoginReq userLoginReq) throws Exception {
        authenticate(userLoginReq.getEmail(), userLoginReq.getPassword());

        System.out.println("controller before loadUserByUsername");
        final UserLoginRes userDetails = (UserLoginRes) userService
                .loadUserByUsername(userLoginReq.getEmail());
        System.out.println("controller after loadUserByUsername");
        final String token = jwtTokenUtil.generateToken(userDetails);

        return ResponseEntity.ok(new JwtResponse(token));
    }

    private void authenticate(String username, String password) throws Exception {
        try {
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
        } catch (DisabledException e) {
            throw new Exception("USER_DISABLED", e);
        } catch (BadCredentialsException e) {
            throw new Exception("INVALID_CREDENTIALS", e);
        }
    }
 

위 코드에 대한 간략한 설명은 아래와 같다.

createAuthenticationToken(
      authentication() -> authenticate() -> loadUserByUsername() -> DB 접속!
         내가 만든거     authenticationManager        서비스
         
      출력 before
      loadUserByUsername() -> DB 접속!
      출력 after
   )
 

디비 접속!이 두번이나 있는데.. 이 코드는 아래 그림과 같은 상황이다.

여기서 문제는 loadUserByUsername이다.

loadUserByUsername이 두번 호출되고 있다.

문제는 loadUserByUsername가 DB select 쿼리를 실행하는 것인데

이렇게 되면 두번이나 디비에 접속하게 되는 것이다.

 

첫번째 접속은 아이디 패스워드 확인이다.

private void authenticate(String username, String password) throws Exception {
        try {
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
        } catch (DisabledException e) {
            throw new Exception("USER_DISABLED", e);
        } catch (BadCredentialsException e) {
            throw new Exception("INVALID_CREDENTIALS", e);
        }
    }
 

authenticate 함수는 void 타입으로 username, password를 확인만 한다.

그리고 두번째 접속으로 email을 통해 해당 사용자 정보를 조회해는 것이다.

 

username, password를 확인하면서 사용자 정보까지 가지고 올 수는 없나.. 했는데

가지고 올 수 있었다.

 

호출하려는 authenticate 메소드가 Authentication을 반환하는데,

이 Authentication 객체는 아래와 같이

사용자의 정보를 담고 있다.

그래서 굳이 사용자 정보를 가지고 오는 두번째 loadUserByUsername 호출은 할 필요가 없는 것이었다.

728x90

댓글