포스트

JWT + 카카오 소셜 로그인 (5)

📌 Server Side

4. 클라이언트로부터 전달 받은 인가 코드를 이용하여 카카오 서버에 토큰 요청

  • 먼저 클라이언트로부터 인가 코드를 받아오는 엔드포인트에서, 카카오 서버에 액세스 토큰을 요청하는 서비스를 호출
1
2
3
4
5
6
/* AuthController.java */
@GetMapping("/kakao")
public ResponseEntity<UserDTO> kakaoLogin(@RequestParam String code) {
  UserDTO userDTO = authService.kakaoLogin(code);
  return ResponseEntity.ok(userDTO);
}
1
2
3
4
5
6
/* AuthService - kakaoLogin 메소드 */
public UserDTO kakaoLogin(String code) {
  KakaoTokenDto kakaoTokenDto = getKakaoAccessToken(code);
  String accessToken = kakaoTokenDto.getAccess_token();
  /* ··· */
}
  • getKakaoAccessToken : 카카오 서버에 액세스 토큰 요청 부분
코드 보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* AuthService - getKakaoAccessToken 메소드 */
public KakaoTokenDto getKakaoAccessToken(String code) {
  HttpHeaders headers = new HttpHeaders();
  headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");

  MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
  params.add("grant_type", "authorization_code");
  params.add("client_id", KAKAO_CLIENT_ID);
  params.add("redirect_uri", KAKAO_REDIRECT_URI);
  params.add("code", code);
  params.add("client_secret", KAKAO_CLIENT_SECRET);

  HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);
  RestTemplate restTemplate = new RestTemplate();

  ResponseEntity<String> response = restTemplate.exchange(
          "https://kauth.kakao.com/oauth/token",
          HttpMethod.POST,
          request,
          String.class
  );
/* ··· */
}

5. 카카오 서버에서 백엔드 서버로 토큰 발행

  • getKakaoAccessToken : 카카오 서버로부터 액세스 토큰 발급 부분
코드 보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* AuthService - getKakaoAccessToken 메소드 */
public KakaoTokenDto getKakaoAccessToken(String code) {
  /* ··· */
  ObjectMapper objectMapper = new ObjectMapper();
  objectMapper.registerModule(new JavaTimeModule());
  objectMapper.configure(DeserializationFeatureFAIL_ON_UNKNOWN_PROPERTIES, false);

  KakaoTokenDto kakaoTokenDto;
  try {
    kakaoTokenDto = objectMapper.readValue(response.getBody(), KakaoTokenDto.class);
  } catch (Exception e) {
    throw new RuntimeException("카카오 토큰을 받아오는 데 실패했습니다.");
  }

  return kakaoTokenDto;
}

6.❗️ 토큰 발급이 완료되면 사용자 정보 조회 후 JWT 토큰 생성

코드 보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* AuthService - kakaoLogin 메소드 */
public UserDTO kakaoLogin(String code) {
  KakaoTokenDto kakaoTokenDto = getKakaoAccessToken(code);
  String accessToken = kakaoTokenDto.getAccess_token();

  KakaoAccountDto kakaoUserInfoDto = getKakaoUserInfo(accessToken);
  /* ··· */
  UserEntity user = userRepository.findByEmail(email).orElseGet(() -> {
  /* ··· */
  });

  String jwt = jwtUtils.generateToken(user);
  String refreshToken = jwtUtils.generateRefreshToken(new HashMap<>(), user);

  UserDTO response = UserDTO.toDTO(user);
  response.setToken(jwt);
  response.setRefreshToken(refreshToken);

  return response;
}
  • 발급받은 accessToken을 사용하여 getKakaoUserInfo 메소드를 통해 카카오 서버의 사용자 정보를 조회
  • 조회한 사용자 정보를 이용하여 DB에 해당 사용자 존재 여부 확인 후 사용자 처리
  • JWT 토큰 및 리프레시 토큰을 생성
  • UserDTO 객체를 생성 및 사용자 정보를 담고, 토큰을 설정하여 반환

✔️ 끝으로

  • 반환한 JWT 토큰을 클라이언트 쪽에서 받아서 사용자 로그인 처리를 완료한다.
  • 이 과정은 클라이언트와 서버 간의 인증을 통해 사용자에게 보다 안전하고 편리한 로그인 경험을 제공한다.
  • 또한, JWT 토큰을 사용함으로써 서버 간의 상태를 유지하지 않고도 인증을 처리할 수 있어 확장성과 보안성을 높일 수 있었다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.