관리 메뉴

가끔 보자, 하늘.

REST API로 카카오톡 메세지 보내기 #02 - python 으로 인증하기 본문

개발 이야기/개발툴 및 기타 이야기

REST API로 카카오톡 메세지 보내기 #02 - python 으로 인증하기

가온아 2021. 12. 8. 12:34

오늘은 Python 으로 카톡 메세지를 보내 보겠습니다.

메세지와 관련된 API 리스트는 공식 개발자 문서에서 "문서" -> "메세지" -> "카카오톡 메세지:REST API"의 "선택 조건에 따른 API" 항목에서 확인할 수 있습니다.

여기서는 "나에게 보내기"를 샘플로 만들어 보겠습니다. API 리스트 하단에 "나에게 보내기" 항목을 보시면 Request와 Response, 그리고 Sample을 확인하실 수 있습니다. 이제 이 내용을 python 코드에서 requests 모듈을 사용해 적용해 보겠습니다. 작업을 위해서는 이전 글에서 언급된 REST API KEY와 REDIRECT_URI를 통해 인가 코드와 인증 토큰을 받아야 합니다. 관련 내용은 이 문서 중 "인가 코드 받기", "토큰 받기"에서 확인하실 수 있습니다.

우선 인가 코드를 받아보겠습니다. 유저의 동의가 필요하기 때문에 terminal 혹은 prompt=none 옵션으로는 자동으로 발급받는 것이 불가능합니다. 발급된 인가 코드는 토큰 발급 시 무효화됩니다. https://kauth.kakao.com/oauth/authorize?response_type=code&client_id={REST_API_KEY}&redirect_uri={REDIRECT_URI} 형식으로 입력해서 직접 동의 절차를 거칩니다. 

전체 동의 후 "동의 후 계속하기"를 누르면 404 에러가 나오는 화면에 나오는데, 주소창을 보면 redirect_uri 주소뒤에 code값이 포함되어 있는 것을 확인 할 수 있습니다. 추가된 이 값이 인가코드 입니다. "?code=" 뒤의 모든 텍스트를 복사해 주세요. 인가 코드를 받았다고 카카오 로그인이 완료된 것은 아니고, 토큰 받기까지 마쳐야 정상적으로 로그인 과정을 완료할 수 있습니다.

이제 토큰을 발급받아 보겠습니다. "토큰 받기"에 대한 상세 내용은 문서를 참고하시면 됩니다. 아래는 python requests 모듈을 사용해 post로 token을 요청하여 출력하는 코드입니다.

import requests
import json

rest_api_key = 'YOUR_REST_API_KEY'
redirect_uri = 'https://example.com/oauth'
url_token = 'https://kauth.kakao.com/oauth/token'
authorize_code = 'YOUR_AUTH_CODE'

data = {
    'grant_type':'authorization_code',
    'client_id':rest_api_key,
    'redirect_uri':redirect_uri,
    'code': authorize_code,
}

response = requests.post(url_token, data=data)
tokens = response.json()
print(tokens)

이렇게 발급된 토큰은 최장 한 달을 사용할 수 있습니다. 그래서 전달받은 토큰 정보를 저장해서 계속 사용할 수 있으며, "토큰 정보 보기"로 해당 토큰이 유효한지, "토큰 갱신하기"로 인가 코드를 다시 받지 않고 계속 갱신하면서 사용할 수 있습니다.  이제 위 코드를 조금 수정해 보겠습니다. 처음 시작할 때 토큰 파일이 있는지 확인 후 없으면 새로 받고, 있다면 유효한지, 유효기간이 지났다면 갱신하는 과정을 추가해 보겠습니다.

import requests
import json

rest_api_key = 'YOUR_REST_API_KEY'
redirect_uri = 'https://example.com/oauth'
url_token = 'https://kauth.kakao.com/oauth/token'
authorize_code = 'YOUR_AUTH_CODE'

try:
    with open("kakao_token.json","r") as fp: # 기존에 저장된 token 파일이 있는지 찾아봅니다.
        tokens = json.load(fp)
        if "error_code" in tokens:
            tokens={}
except Exception as e:
    print(e)
    tokens={}

if tokens == {}:
    # 신규 발급이 필요한 경우
    param = {
        'grant_type':'authorization_code',
        'client_id':rest_api_key,
        'redirect_uri':redirect_uri,
        'code': authorize_code, # 한번 발급되면 authorize_code는 무효화됩니다. 
    }

    response = requests.post('https://kauth.kakao.com/oauth/token', data=param)
    tokens = response.json() # token 발급 api로 발급된 정보들을 kakao_token.json 파일에 저장합니다.
    if "error_code" in tokens:
        print(tokens["error_code"])
    else:
        with open("kakao_token.json","w") as fp:
            json.dump(tokens, fp)
            print("파일로 토큰 정보 저장!")
else:
	# 기존 발급된 정보가 있을 경우
    headers = {
        "Authorization": "Bearer " + tokens["access_token"]
    }
    # access_token_info의 결과가 계속 -401로 돌아옵니다. 추후 수정할 예정입니다.
    response = requests.get('https://kapi.kakao.com/v1/user/access_token_info', headers=headers)
    result = response.json()
    if "error_code" in result:
    	# -401은 유효하지 않은 값 혹은 유효기간이 지난 토큰일 경우 발생하는 에러입니다.
        # api로 token 갱신을 요청합니다.
        param = {
            "grant_type":"refresh_token",
            "client_id" : rest_api_key,
            "refresh_token" : tokens["refresh_token"]
        }
        response = requests.post('https://kauth.kakao.com/oauth/token', data=param)
        new_token = response.json()
        
        # 새로 발급된 token을 다시 저장합니다.
        if "error_code" in new_token:
            print("ERROR :", new_token["error_code"])
        else:
            with open("kakao_token.json", "w") as fp:
                json.dump(new_token, fp)
                print("파일로 새로운 토큰 정보 저장!")
    else:
        print("정상 토큰")

하다보니 오늘도 메세지를 보내지는 못했네요. 내일은 실제 메세지를 꼭 보내보겠습니다. :)

반응형