리눅스/Window10 Arch Linux

Window 10 Intellij Maven으로 생성한 SpringBoot 프로젝트 카카오 로그인 REST API 적용 설명

차세대 IT 리더 비공자 2024. 8. 30. 16:31

 

목록

1. 카카오에서 로그인 후, 돌아왔을 때 처리

2. 사용된 객체 설명

3. 통신 흐름

 

 

 

카카오 로그인 버튼을 클릭 했을 때,

카카오 로그인 페이지로 리다이렉트

@PostMapping("/kakaoLogin")
public String kakaoLogin() {
    // 카카오 로그인 페이지로 리다이렉트하기 위한 URL을 생성합니다.
    String kakaoLoginUrl = "https://kauth.kakao.com/oauth/authorize?client_id=" + kakaoRestApiKey
                           + "&redirect_uri=" + kakaoRedirectUri
                           + "&response_type=code";

    // 생성한 URL로 리다이렉트 합니다.
    // 생성한 리다이렉트 URL : 카카오 로그인 페이지 화면 ( 카카오에서 제공 )
    return "redirect:" + kakaoLoginUrl;
}

통신 흐름

1. 사용자가 카카오 로그인을 요청하면, 서버는 카카오 로그인 페이지로

    리다이렉트할 URL을 생성합니다.

2. 이 URL에는 카카오 REST API 키, 리다이렉트 URL, 응답 유형이 포함

3. 서버는 사용자를 카카오 로그인 페이지로 사용자에게 리다이렉트 해줍니다.

 

 

1. 카카오에서 로그인 후, 돌아왔을 때 처리

@GetMapping("/kakaoLoginCallBack")
public String kakaoLoginCallBack(@RequestParam("code") String code, Model model, HttpSession session) {
    // RestTemplate 객체를 생성합니다. HTTP 요청을 보내기 위해 필요합니다.
    RestTemplate restTemplate = new RestTemplate();

    // 카카오로부터 액세스 토큰을 요청할 URL을 설정합니다.
    String tokenUrl = "https://kauth.kakao.com/oauth/token";

    // 액세스 토큰 요청에 필요한 파라미터를 담을 MultiValueMap을 생성합니다.
    MultiValueMap<String, String> tokenParams = new LinkedMultiValueMap<>();
    tokenParams.add("grant_type", "authorization_code");
    tokenParams.add("client_id", kakaoRestApiKey);
    tokenParams.add("redirect_uri", kakaoRedirectUri);
    tokenParams.add("code", code);

    // 요청 헤더를 설정합니다. Content-Type을 application/x-www-form-urlencoded로 설정합니다.
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

    // 요청 본문을 설정합니다. 본문에 파라미터를 포함시킵니다.
    HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(tokenParams, headers);

    try {
        // POST 요청을 보내서 액세스 토큰을 받습니다.
        ResponseEntity<Map> tokenResponse = restTemplate.postForEntity(tokenUrl, request, Map.class);

        // 응답에서 액세스 토큰을 추출합니다.
        String accessToken = (String) tokenResponse.getBody().get("access_token");

        // 액세스 토큰을 사용하여 사용자 정보를 요청할 URL을 설정합니다.
        String userInfoUrl = "https://kapi.kakao.com/v2/user/me";

        // 사용자 정보 요청 시 헤더에 Authorization을 추가합니다.
        HttpHeaders userHeaders = new HttpHeaders();
        userHeaders.set("Authorization", "Bearer " + accessToken);
        HttpEntity<String> userRequest = new HttpEntity<>(userHeaders);

        // GET 요청을 보내서 사용자 정보를 받습니다.
        ResponseEntity<Map> userResponse = restTemplate.exchange(userInfoUrl, HttpMethod.GET, userRequest, Map.class);

        // 응답에서 사용자 정보를 추출합니다.
        Map<String, Object> kakaoAccount = (Map<String, Object>) userResponse.getBody().get("kakao_account");

        // 사용자 정보를 추출하여 UserDTO 객체를 생성합니다.
        String userName = ((Map<String, String>) kakaoAccount.get("profile")).get("nickname");
        String userId = userResponse.getBody().get("id").toString();

        UserDTO userDTO = new UserDTO();
        userDTO.setUserName(userName);
        userDTO.setUserId(userId);

        // UserDTO 객체를 데이터베이스에 저장합니다.
        userService.kakaoSave(userDTO);

        // 사용자 정보를 모델에 추가하여 JSP 페이지에서 사용할 수 있도록 합니다.
        session.setAttribute("userName", userName);
        session.setAttribute("userId", userId);
        model.addAttribute("userName", userDTO.getUserName());

        // 홈 페이지로 리다이렉트합니다.
        return "redirect:"+"/";
    } catch (HttpClientErrorException e) {
        // HTTP 오류가 발생한 경우, 오류 코드와 응답 본문을 출력합니다.
        System.out.println("HTTP Error: " + e.getStatusCode());
        System.out.println("Response Body: " + e.getResponseBodyAsString());

        // 에러가 발생한 경우, 에러 페이지로 리다이렉트합니다.
        return "error";
    }
}

 

2. 사용된 객체 설명

사용된 객체 설명
@RequestParam
("code")
이 부분은 URL에 포함된 "code" 파라미터를 받아옵니다. 카카오는 사용자가 로그인을 성공하면 "code"라는
인가코드를 서버로 전달
합니다. 이 코드는 나중에 접근토큰을 요청할 때 사용됩니다.
Model model 객체는 서버에서 생성한 데이터를 뷰(JSP 페이지 등)에 전달하는데 사용됩니다. 예를 들어,
로그인한 사용자의 이름을 모델에 담아 뷰( JSP 페이지 )에서 표시할 수 있습니다.
HttpSession HttpSession 객체는 서버와 클라이언트 간의 세션을 관리합니다. 세션을 사용하면 사용자가 웹 사이트를 떠나지 않는 한 사용자의 상태( 예 : 로그인 상태 )를 유지할 수 있습니다. 여기서는 사용자의 이름과 사용자의ID를 세션에 저장하여 로그인 상태를 유지합니다.
( Session에 대한 시간은 WebConfig 클래스 파일에서 설정했음 )
RestTemplate RestTemplate은 스프링 프레임워크에서 제공하는 HTTP 클라이언트 도구입니다.
도구를 사용하면 외부 서버( 여기서 카카오 서버 )와 통신할 수 있습니다.
RestTemplate은 다양한 HTTP 메서드( GET, POST 등 )를 사용하여 데이터를 주고 받을 수 있습니다.
MultiValueMap 이 객체는 여러 개의 값을 가질 수 있는 Map입니다.
여기서는 액세스 토큰을 요청할 때 필요한 파라미터를 담는 데 사용됩니다.
MultiValueMap은 하나의 키에 여러 개이 값을 저장할 수 있어,
HTTP 요청의 파라미터를 구성하기에는 적합합니다.


접근토큰 요청에 필요한 파라미터를 담은 MultiValueMap

HttpHeaders HTTP 요청의 헤더 정보를 담는 객체입니다. 헤더에는 요청의 메타데이터(예: 콘텐츠 유형, 인증 정보 등)가 포함됩니다. 여기서는 Content-Type을 설정하거나, 사용자 정보 요청 시 인증 토큰을 헤더에 포함시킵니다.
HttpEntity HTTP 요청이나 응답에 사용되는 본문과 헤더 정보를 포함하는 객체입니다. HttpEntity는 요청을 보낼 때, 본문과 헤더를 함께 설정하는 데 사용됩니다.
ResponseEntity HTTP 응답을 포함하는 객체입니다. ResponseEntity는 응답 상태 코드, 헤더, 본문을 포함합니다. 여기서는 카카오 서버로부터 받은 응답(토큰이나 사용자 정보)을 처리하는 데 사용됩니다.
Map Map 객체는 키-값 쌍으로 데이터를 저장합니다. 여기서는 카카오 서버에서 받은 JSON 응답을 파싱하여 필요한 정보를 추출하기 위해 사용됩니다.

 

3. 통신 흐름

  • 사용자가 카카오 로그인을 완료하면, 카카오는 서버로 인가 코드를 보냅니다.
  • 서버는 RestTemplate을 사용해 카카오 서버에 인가 코드를 보내고, 액세스 토큰을 요청합니다.
  • 카카오 서버는 액세스 토큰을 반환합니다.
  • 서버는 이 액세스 토큰을 사용해 카카오 서버에서 사용자 정보를 요청합니다.
  • 카카오 서버는 사용자의 정보를 반환합니다.
  • 서버는 반환된 사용자 정보를 UserDTO 객체에 저장하고, 이를 데이터베이스에 저장합니다.
  • 서버는 사용자 이름을 세션에 저장하여 로그인 상태를 유지하고, 홈 페이지로 리다이렉트합니다.