교차 출처 리소스 공유(Cross-origin resource sharing, CORS), 교차 출처 자원 공유는 웹 페이지 상의 제한된 리소스를 최초 자원이 서비스된 도메인 밖의 다른 도메인으로부터 요청할 수 있게 허용하는 구조이다. 웹페이지는 교차 출처 이미지, 스타일시트, 스크립트, iframe, 동영상을 자유로이 임베드할 수 있다. 특정한 도메인 간(cross-domain) 요청, 특히 Ajax 요청은 동일-출처 보안 정책에 의해 기본적으로 금지된다.

환경

  • Spring Boot (Server)

    • Version : 2.3.0.RELEASE 

    • Port : 8080

  • Angular (Client)

    • Version : 8.2.14

    • Port : 4300


위의 환경 정보에서 Spring Boot, Angular의 Port를 보면 CORS 상황인걸 확인할 수 있다.

Angular에서 카카오 API 인증 요청

  • Kakao Request Guide

GET /oauth/authorize?client_id={REST_API_KEY}&redirect_uri={REDIRECT_URI}&response_type=code HTTP/1.1
Host: kauth.kakao.com

위의 Guide를 보면 client_id, redirect_uri, response_type을 매개변수로 받는것을 알 수 있다.

  • Sample 1

http://kauth.kakao.com//oauth/authorize?client_id=123123123123123123123&redirect_uri=http://localhost:8080/kakao&response_type=code

위의 Sample을 확인해 보면 아래의 3가지 매개변수를 입력한걸 알 수 있다.

client_id : 123123123123123123123

redirect_uri : http://localhost:8080/oauth/kakao

reponse_type : code

 

여기서 redirect_uri가 중요하다.

 

oAuth2의 기본 개념은 Angular(Client)가 Kakao API를 호출하면 Angular(Client)에게 응답을 주는게 맞다.

하지만 Rest API 호출 상황에서는 Kakao API가 Angular(Client)에게 응답을 줄수 있는 방법이 없다.

그래서 redirect_uri를 Spring Boot(Server)로 받아야 한다.

Rest API로 Angular(Client)에서 응답 받는 방법이 없다고 판단하였으나 혹시 모르니 조금 더 찾아보려 한다.
※ Angular(Client)가 Kakao API의 JavaScript 고급가이드대로 Login 하면 가능하다.
하지만 Kakao API 문서에 따르면 앞으로 oAuth 중요 정보인 Refresh Token을 제공하지 않을 계획이라고 명시하였다.
Kakao Developers JavaScript 로그인 API 고급가이드를 참고바란다.

Spring Boot 로직 처리

@GetMapping("/kakao")
public void kakaoLogin(String code, HttpServletRequest request, HttpServletResponse response) throws Exception {
	try {
		RestTemplate rest = new RestTemplate();
          // 사용자 인증정보 받기 위한 세팅
          MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
          map.add("grant_type", "authorization_code");
          map.add("client_id", "12312312312312312312312312");
          map.add("redirect_uri", "http://localhost:8080/oauth/kakao");
          map.add("code", code);

          HttpHeaders headers = new HttpHeaders();
          headers.add("Context-type", "application/json");

          HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(map, headers);

          // 사용자 인증정보 요청
          ResponseEntity<Map> rs = rest.postForEntity("https://kauth.kakao.com/oauth/token", entity, Map.class);

          // access_token, refresh_token Get
          String Access = rs.getBody().get("access_token").toString();
          String Refresh = rs.getBody().get("refresh_token").toString();

          // 회원 가입 프로세스
          {
              ...
          }

          // Cookie, Response			
          {
              Cookie accessCookie 	= // 쿠키생성
              Cookie refreshCookie 	= // 쿠키생성

              response.addCookie(accessCookie);
              response.addCookie(refreshCookie);

              // Angular로 Redirect
              response.sendRedirect("http://localhost:4300");
          }

	} catch (Exception e) {
		e.printStackTrace();
	}
}

위의 소스를 보면 code를 Kakao API에서 redirect 받는다.

 

받은 인증 코드를 이용하여 사용자 인증정보(access_token, refresh_token)을 요청하고 Cookie를 만들어 response.sendRedirect를 이용하여 Angular(Client)에 redirect하면 정상적으로 Kakao Login이 완료된다.


두서 없이 Kakao Login을 처음 구현하면서 격은 문제점을 보완해서 글을 작성하였습니다. 처음 접하는거라 많이 부족하기도 하고 모르는 것도 많았습니다. 부족한 부분이나 틀린 부분이 있다면 언제든지 지적 해주세요.

 

읽어주셔서 감사합니다.

 

참고 자료

+ Recent posts