카카오로그인

크리스탈 파워~UP·2021년 3월 7일
3

api

목록 보기
1/1

카카오 로그인?

기본적인 동작구조

  • 사용자가 앱에서 카카오 로그인 버튼을 클릭합니다.
  • 사용자가 '카카오톡으로 로그인'을 선택하면 카카오톡 실행 또는 실행 중인 카카오톡으로 연결되고, '다른 카카오계정으로 로그인'을 선택하면 직접 계정 정보를 입력하는 화면이 출력됩니다. 카카오톡이 설치되어 있지 않은 기기나 PC 웹 환경에서는 직접 계정 정보를 입력하여 카카오계정으로 로그인하게끔 진행됩니다.
  • '카카오톡으로 간편로그인'한 경우, 카카오톡에 연결된 카카오계정의 자격정보(Credentials)를 통해 사용자를 인식합니다. 직접 카카오계정을 입력해 로그인한 경우에는 해당 계정의 자격정보로 인식합니다.
  • 자격정보가 올바르다면 카카오 로그인 동의 화면을 통해 사용자로부터 사용자 정보 및 기능 활용 동의를 받습니다.
  • 사용자가 필수 항목에 동의하고 로그인을 요청하면 인가 코드(Authorization Code)가 발급됩니다. 이 코드는 앱 정보의 Redirect URI에 전달됩니다.
  • 앱은 전달 받은 인가 코드를 기반으로 토큰을 요청하고 받습니다.

카카오 로그인은 카카오계정의 사용자 자격정보로 인가 코드를 받아오고, 인가 코드로 액세스 토큰과 리프레시 토큰을 얻는 과정으로 구성돼 있습니다. 액세스 토큰은 사용자를 인증하고 카카오 API 호출 권한을 부여합니다. 리프레시 토큰(Refresh Token)은 사용자가 매번 카카오계정 정보를 입력하거나 카카오톡으로 로그인하지 않고도 액세스 토큰을 발급받을 수 있게 합니다.

사용자 환경에 따른 인증방법


Kakao Developers에서 할일

  1. Kakao Developers에 앱 등록하기
    1. https://developers.kakao.com/ 접속
    2. 상단 메뉴 중 내 애플리케이션
    3. 애플리케이션 추가하기
    4. 앱 아이콘, 앱 이름, 사업자명 등록
    • 어플 삭제는 일반메뉴→앱삭제 선택시 가능
  2. 앱 키 ( REST API키) 보관
  3. 플랫폼 → Web 플랫폼 등록
    사이트 도메인 등록
    (O) https://example.com
    (X) https://www.example.com
  4. 제품설정 → 카카오로그인
    활성화하기 : OFF→ON
    Redirect URL 등록 (로그인 매핑 주소 등록)
  5. 동의 항목설정 하기(필수 및 선택 항목 설정)

어플리케이션 로직 상에서 할일

1. 인가코드 받기

  1. 간편로그인(카카오로그인) 버튼을 눌렀을 때 함수 fn_snsLogin('kakao'); 실행 하도록 하기
<div class="social-container">
    <div class="col">
    	<img src="${path }/resources/images/login/kakao.png"
    			alt="카카오로그인" class="sns-icon"  onclick="fn_snsLogin('kakao');"/>
    </div>
</div>

<script>
   function fn_snsLogin(sns){
    	let sendUrl=""; 
    	console.log(sns);
    	if(sns=="naver"){
    		sendUrl="${naver_url }";		
    	}else if(sns=="kakao"){   					 
       	 	sendUrl="https://kauth.kakao.com/oauth/authorize?client_id=RESTAPI키&redirect_uri=등록한 리다이렉트URI&response_type=code";
    	}else if(sns=="google"){
    		sendUrl= googleUrl="${google_url}";	
    	}
    	location.replace(sendUrl);
    }
</script>
  • fn_snsLogin(sns)의 매개변수 sns는 여러 간편로그인을 지정했을 시 각각의 요청할 주소를 가져가기 위한 구분자 역할

인가 코드를 받기 위한 Request
- URI

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

- 실제 요청 주소
https://kauth.kakao.com/oauth/authorize?client_id=REST API키&redirect_uri=https://rclass.iptime.org/20PM_BOM_final/auth/kakao/callback&response_type=code

- 요청시 파라미터

response 응답 : 로그인 성공시

HTTP/1.1 302 Found
Content-Length: 0
Location: {REDIRECT_URI}?code={AUTHORIZE_CODE}

2. 토큰 받기

해당 API는 인가 코드로 액세스 토큰과 리프레시 토큰을 발급받는 API.
필수 파라미터 값들을 담아 POST로 요청.
요청 성공 시, 응답은 JSON 객체로 Redirect URI에 전달되며 두 가지 종류의 토큰 값과 타입, 초 단위로 된 만료 시간을 포함함.

  1. 인가코드 받기 시 REDRECT URI로 등록한 콜백주소로 code 전달됨
 //SnsController.java
 @RequestMapping("/auth/kakao/callback")
 public String kakaoLogin(Model model, 
    @RequestParam(value = "code", required = false) String code,
    HttpServletRequest request) throws Exception{

    	//상제로직 작성란...
 }
  1. 받은 코드를 이용해서 access_token 받아오기.
//SnsController.java
//인가코드 매개변수로 전달해서 access_token 받아오기 
String access_Token=kakaoService.getAccessToken(code);

토큰 받아오는 방법

POST /oauth/token HTTP/1.1
Host: kauth.kakao.com
Content-type: application/x-www-form-urlencoded;charset=utf-8

Sample

Request

    curl -v -X POST "https://kauth.kakao.com/oauth/token" \
     -d "grant_type=authorization_code" \
     -d "client_id={REST_API_KEY}" \
     -d "redirect_uri={REDIRECT_URI}" \
     -d "code={AUTHORIZATION_CODE}"

Response

    HTTP/1.1 200 OK
    Content-Type: application/json;charset=UTF-8
    {
        "token_type":"bearer",
        "access_token":"{ACCESS_TOKEN}",
        "expires_in":43199,
        "refresh_token":"{REFRESH_TOKEN}",
        "refresh_token_expires_in":25184000,
        "scope":"account_email profile"
    }

3. 사용자 정보 가져오기

GET/POST /v2/user/me HTTP/1.1
Host: kapi.kakao.com
Authorization: Bearer {ACCESS_TOKEN}
Content-type: application/x-www-form-urlencoded;charset=utf-8
  1. access_token을 이용해서 정보 가져오기.
    //KakaoController.java
    //access_token으로 사용자 정보 가져오기
    HashMap<String,Object> userInfo=kakaoService.getUserInfo(access_Token);

응답예제

    json{4 items
    "id":float9876543211234
    "properties":{3 items
    	"nickname":string"홍길동"
    	"thumbnail_image":string"http://xxx.kakao.co.kr/.../aaa.jpg"
    	"profile_image":string"http://xxx.kakao.co.kr/.../bbb.jpg"
    }
    "kakao_account":{9 items
    	"profile_needs_agreement":boolfalse
    	"profile":{1 item
    		"nickname":string"jaden.h"
    	}
    	"has_birthday":boolfalse
    	"birthday_needs_agreement":boolfalse
    	"has_ci":boolfalse
    	"ci_needs_agreement":boolfalse
    	"legal_name_needs_agreement":boolfalse
    	"legal_birth_date_needs_agreement":boolfalse
    	"legal_gender_needs_agreement":boolfalse
    }
    "connected_at":string"2020-03-04T05:45:55Z"
    }
      

실제 적용코드

//KakaoService.java
public HashMap<String, Object> getUserInfo (String access_Token) {

       HashMap<String, Object> userInfo = new HashMap<>();
       String reqURL = "https://kapi.kakao.com/v2/user/me";
       try {
           URL url = new URL(reqURL);
           HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    	   //요청 메소드
           conn.setRequestMethod("POST");
    	   //요청에 필요한 Header에 포함될 내용
           conn.setRequestProperty("Authorization", "Bearer " + access_Token);
    			
    	   //응답완료코드
           int responseCode = conn.getResponseCode();
           System.out.println("responseCode : " + responseCode);

           BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));

           String line = "";
           String result = "";

           while ((line = br.readLine()) != null) {
               result += line;
           }
           System.out.println("response body : " + result);

           JsonParser parser = new JsonParser();
           JsonElement element = parser.parse(result);

           String id = element.getAsJsonObject().get("id").getAsString();
           JsonObject properties = element.getAsJsonObject().get("properties").getAsJsonObject();
           JsonObject kakao_account = element.getAsJsonObject().get("kakao_account").getAsJsonObject();
           String email=null;
           if(kakao_account.getAsJsonObject().get("email")!=null) {
          	 email = kakao_account.getAsJsonObject().get("email").getAsString();
           }
           String nickname = properties.getAsJsonObject().get("nickname").getAsString();
           String profile_image = properties.getAsJsonObject().get("profile_image").getAsString();

           userInfo.put("id", id);
           userInfo.put("email", email);
           userInfo.put("nickname", nickname);
           userInfo.put("profile_image", profile_image);

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

       return userInfo;
    }
  1. HashMap<String,Object>에 담아 온 회원정보를 Member객체에 담아 기존 회원정보와 비교하기

출처 및 참고 사이트

profile
코딩러너! 걷지말고 뛰어라~

0개의 댓글