우당탕탕

[앱출시 - 1] REST API 소셜로그인 (네이버,카카오,구글,페이스북) - 카카오 본문

앱출시관련

[앱출시 - 1] REST API 소셜로그인 (네이버,카카오,구글,페이스북) - 카카오

모찌모찝 2022. 8. 19. 11:28

오늘은 산타 앱 개발의 시작인 소셜 로그인에 대해 포스팅하려 한다. 
초기의 산타 앱에서는 네이버, 카카오, 구글, 페이스북 로그인만 존재하였고, REST API 방식으로 개발을 진행했었다. 
마지막 후기 때 작성할 예정이지만... 구글, 페이스북 로그인은 현재 앱에서 빠져있는 상태이다.. ( 이유는 나중에 )

개발 ( Springboot )

일단 개발에 앞서 각각의 개발자 사이트에 접속해서 앱 등록 및 개발 준비를 해야 한다

1. 카카오 개발자 - https://developers.kakao.com/
2. 네이버 개발자 - https://developers.naver.com/main/
3. 구글 개발자 - https://console.developers.google.com/apis/
4. 페이스북 개발자 - https://developers.facebook.com/?locale=ko_KR

해당 사이트 들에서 전부 로그인을 진행하고 카카오부터 설명을 시작하겠다
카카오의 경우 해당 URL에 접속한 뒤 내 애플리케이션 추가를 눌러 내가 개발할 앱의 이름과 사진 등을 추가하면 만들어진다

앱 이름만 적고 넘어가도 나중에 변경 가능하다!! 
작성을 하고 나면 밑에 사진처럼 KEY 값이 생성되는데 REST API로 개발을 진행했기 때문에 REST API 키만 가지고 진행을 할 것이다! 

첫 번째로 진행할 것은 카카오 로그인에서 상태를 활성화시켜주는 것이다 

이후 Redirect URI를 설정해주면 끝나는데 이는 밑에 코드를 작성하면서 설정하면 된다

순서

  1. 카카오 로그인 이미지나 a 태그를 클릭 시 아래의 URL로 접속하게 만들면 설정한 redirect_uri로 카카오 측에서 code 값과 함께 리턴을 해준다. 
  2. code값을 가지고 Controller에서 access_token을 받기 위한 API를 쏜다.
  3. access_token , refresh_token 등의 데이터를 받고 회원정보 API를 요청하여 해당 토큰의 유저 정보를 받아온다.

https://kauth.kakao.com/oauth/authorize?response_type=code&client_id=[카카오 API 키]&redirect_uri=[설정 Redirect URI]

해당 URL로 호출하게 되면 카카오 로그인 창이 뜨게 되는데 카카오 API 키와 설정 Redirect URI를 작성해주고 호출하면 된다
산타의 경우에는 프로퍼티 파일에 KEY 값을 설정해놓고 서버 URL 의경우 공통 코드로 빼놓고 사용해서 이런 식으로 사용했다.

산타의 경우 로컬 기준 "http://localhost:8080/auth/kakao/callback" 으로 redirect url을 설정해서 작업을 했으며 카카오 개발자 도구에도 이와 같이 등록했다. 서버 주소로 나중에 변경하게 되면 추가로 카카오에 등록해주면 된다.


JSONObject를 이용하기 위해선 build.gradle에 추가해줘야 한다

implementation 'org.json:json:20171018'


이제 회원가입 및 로그인 컨트롤러 코드를 보겠다 ( 코드는 따로 아래에 첨부 )

@RequestParam으로 code값을 받는 이유는 카카오 로그인을 진행하면 쿼리파람으로 ?code = {값} 이 들어오게 된다  이후 컨트롤러에서 API전송을 위해 헤더를 설정해주고 params값을 설정해주면 된다. 산타의 경우 kakao_rest = key값 SERVER_URL = 서버 주소로 설정해놨다.

요청을 보내고 토큰 결과를 받게 되면 status code와 "access_token" , "refresh_token" , "token_type" 등이 리턴된다.
산타는 access토큰을 가지고 유저 정보 조회를 진행한 뒤 해당 social ID 값으로 디비를 조회 후 없는 아이디 일시 회원가입처리 / 존재하는 아이디 일시 세션에 social ID를 넣고 로그인 처리를 진행하였다.

토큰결과값 아래의 코드이다

해당 방식으로 요청 시 jo2에는 로그인 일시 카카오 이메일 , 소셜 아이디, 썸네일 이미지 등 정보들이 담겨 나온다. 이제 이 정보를 토대로 로그인 및 회원가입 분기 처리를 따로 개발하면 카카오 로그인/회원가입은 완성이다! 

간단한 회원가입을 시키려면 아이디 값/유저 이미지만 받고 넘겨도 괜찮을 거 같고 공통된 데이터를 저장하고 싶으면 모든 정보를 넘겨 커스텀 회원가입페이지에 자동 입력되게 만들면 될 거 같다. 산타는 커스텀 페이지를 이용해 휴대폰 번호, 닉네임, 이메일 등을 받도록 개발하였다.

산타의 경우 사이드 프로젝트로 단일 서버만 생각하여 이런 식으로 개발을 진행하였는데, 만약 큰 프로젝트 및 만든 사이드 프로젝트가 규모가 커지면 스케일 아웃이 필요할 것이다. 이럴 때에는 데이터를 JWT 토큰에 담아 레디스를 이용하여 모든 서버가 레디스를 바라보게 만들면 될 거 같다.

스케일 업 - 스케일 업이란 기존 서버를 좀 더 높은 성능의 서버로 업그레이드시키는 것이다. ex ) 메모리 및 CPU 업그레이드
스케일 아웃 - 스케일 아웃은  서버를 여러 대 추가하여 확장하는 방법이다

세션처리방법

산타의 경우 리턴을 ResponseEntity로 공통화하여 진행하였으며, 공통적으로 Status값, Message값, Data값을 response로 주었다.

아래는 전체 코드를 첨부한다.

    @GetMapping(value = "auth/kakao/callback")
    public ResponseEntity<Message> KakaoLogin(@RequestParam("code") String code ,HttpServletRequest request){
        Message msg = new Message();
        RestTemplate rt = new RestTemplate();
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.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_rest);
        params.add("redirect_uri",SERVER_URL + "/auth/kakao/callback");
        params.add("code",code);

        HttpEntity<MultiValueMap<String,String>> kakaoTokenRequest = new HttpEntity<>(params,httpHeaders);

        ResponseEntity<String> response = rt.exchange(
                "https://kauth.kakao.com/oauth/token",
                HttpMethod.POST,
                kakaoTokenRequest,
                String.class
        );

        // 토큰값 Json 형식으로 가져오기위해 생성
        JSONObject jo = new JSONObject(response.getBody());

        // 토큰결과값
        log.debug("kakao token result = {} " , response);

        RestTemplate rt2 = new RestTemplate();
        HttpHeaders headers2 = new HttpHeaders();

        headers2.add("Authorization", "Bearer "+ jo.get("access_token"));
        headers2.add("Content-type","application/x-www-form-urlencoded;charset=utf-8");

        HttpEntity<MultiValueMap<String,String >> kakaoProfileRequest2= new HttpEntity<>(headers2);

        ResponseEntity<String> response2 = rt2.exchange(
                "https://kapi.kakao.com/v2/user/me",
                HttpMethod.POST,
                kakaoProfileRequest2,
                String.class
        );

        // 토큰을 사용하여 사용자 정보 추출
        JSONObject jo2 = new JSONObject(response2.getBody());
        log.debug("###### kakao login = {}", jo2);

        // 이후 유저 여부를 판단하고 회원가입 / 로그인 처리를 진행하면된다 

        return new ResponseEntity<>(msg, HttpStatus.OK);
    }

 

네이버는 다음 포스팅에서..

Comments