[튜토리얼] 키움 REST API 인증 — 접근토큰 발급과 관리
이 글의 범위
이전 글에서 App Key/Secret을 발급받고 모의투자 계좌까지 준비했다면, 이제 실제로 API를 호출하기 위한 인증 단계가 남는다. 이 글은 키움증권 REST API가 공개 문서에서 안내하는 접근토큰 발급·관리 흐름을 일반화해서 정리한다. 실제 요청 예시나 응답값은 담지 않으며, 개념과 의사코드 위주로 진행한다. 정확한 엔드포인트와 파라미터는 키움증권 공식 API 문서를 반드시 참고해야 한다.
접근토큰(Access Token)이 필요한 이유
App Key/Secret은 "이 앱이 누구인지"를 증명하는 값이지, 매 요청마다 그대로 실어 보내는 값이 아니다. 대신 이 한 쌍으로 먼저 접근토큰을 발급받고, 이후 모든 API 호출에는 그 토큰만 실어 보내는 구조를 쓴다. OAuth 2.0 계열 인증에서 흔히 쓰이는 패턴이고, 키움증권 REST API도 이 방식을 따른다.
이렇게 나누는 이유는 명확하다. App Key/Secret이 노출되면 피해가 크지만, 토큰은 유효기간이 짧고 필요하면 즉시 폐기·재발급이 가능해서 위험을 줄일 수 있다.
일반적인 흐름은 이렇다.
- App Key/Secret으로 토큰 발급 엔드포인트에 요청을 보낸다
- 서버가 접근토큰과 만료 시각(또는 유효시간)을 응답한다
- 이후 모든 API 호출 헤더에 이 토큰을 실어 보낸다
- 토큰이 만료되면 같은 절차를 반복해 재발급받는다
토큰 발급 — 의사코드
실제 엔드포인트 경로나 요청 파라미터명은 키움증권 문서 기준으로 따로 확인해야 한다. 아래는 개념을 보여주기 위한 일반화된 예시다.
python 코드 보기
import os
import time
class KiwoomAuthClient:
def __init__(self, app_key: str, app_secret: str, base_url: str):
self.app_key = app_key
self.app_secret = app_secret
self.base_url = base_url
self._token = None
self._expires_at = 0
def get_access_token(self) -> str:
"""캐시된 토큰이 유효하면 재사용, 아니면 재발급."""
if self._token and time.time() < self._expires_at - 60:
return self._token
self._issue_token()
return self._token
def _issue_token(self) -> None:
"""실제로는 문서에 명시된 토큰 발급 엔드포인트에 POST.
요청 본문에 app_key/app_secret을 담아 보내는 형태가 일반적이다."""
response = self._request_new_token()
self._token = response["access_token"]
self._expires_at = time.time() + response["expires_in"]
def _request_new_token(self) -> dict:
raise NotImplementedError # requests.post(...) 등으로 구현
auth = KiwoomAuthClient(
app_key=os.environ["KIWOOM_APP_KEY"],
app_secret=os.environ["KIWOOM_APP_SECRET"],
base_url=os.environ.get("KIWOOM_BASE_URL", ""),
)여기서 눈여겨볼 부분은 만료 시각보다 60초 여유를 두고 재발급을 트리거하는 부분이다. 정확히 만료 시점에 맞춰 재발급을 시도하면, 네트워크 지연 때문에 "토큰이 만료된 채로 요청이 나가는" 경계 상황이 생길 수 있다. 여유 시간을 두는 건 실전에서 자주 쓰는 방어적 습관이다.
발급받은 토큰으로 요청 헤더 구성하기
토큰을 받았으면, 이후 API 호출에는 이 토큰을 인증 헤더에 실어 보낸다.
python 코드 보기
def build_auth_headers(auth_client: KiwoomAuthClient) -> dict:
token = auth_client.get_access_token()
return {
"Authorization": f"Bearer {token}",
"appkey": auth_client.app_key,
}헤더 이름이나 형식(Bearer 접두사 여부 등)은 증권사 문서마다 다를 수 있으므로, 이 부분만큼은 반드시 키움증권 공식 문서의 최신 스펙을 확인해서 맞춰야 한다.
토큰 만료와 재발급을 자동화해야 하는 이유
자동매매 프로세스는 짧으면 몇 시간, 길면 며칠씩 끊기지 않고 돌아간다. 토큰 유효시간이 몇 시간 단위로 제한돼 있다면, 프로세스가 살아있는 동안 최소 한 번 이상은 토큰이 만료된다. 이걸 사람이 수동으로 재발급해주는 구조로 짜면 반드시 장애로 이어진다.
그래서 실전에서는 아래와 같은 방어 로직을 반드시 넣는다.
- API 호출 전에 토큰 유효성을 확인하고, 만료 임박이면 먼저 재발급
- API 호출 응답이 "인증 실패/토큰 만료" 류의 에러를 반환하면, 토큰을 강제로 재발급받고 한 번만 재시도
- 재발급 자체가 반복 실패하면(예: App Key/Secret 문제) 무한 재시도하지 않고 알림을 보내고 중단
세 번째 항목이 특히 중요하다. 재발급이 계속 실패하는데 무한정 재시도만 하면, 조용히 자금 관리 로직이 멈춘 채로 방치될 수 있다.
처음 연동할 때 자주 하는 실수
- 토큰을 코드나 로그에 그대로 출력하는 것: 디버깅 중
print(token)같은 코드를 남겨두면 로그 파일에 토큰이 그대로 남는다. 로그에는 토큰 값 대신 "발급 성공/실패" 같은 상태만 남겨야 한다. - 토큰 만료 시간을 하드코딩하는 것: 응답에 담긴
expires_in값을 쓰지 않고 "대략 6시간이겠지"라고 임의로 상수를 박아두면, 정책이 바뀌었을 때 조용히 깨진다. - 여러 프로세스가 토큰 발급을 동시에 요청하는 것: 같은 앱으로 여러 스크립트를 동시에 돌리면 토큰 발급 API에 불필요하게 부하를 주거나 요청 한도에 걸릴 수 있다. 토큰을 한 곳에서 발급·캐싱해 여러 프로세스가 공유하는 구조가 안전하다.
오늘의 정리
- 키움 REST API는 App Key/Secret으로 접근토큰을 먼저 발급받고, 이후 요청 헤더에 그 토큰을 싣는 구조를 따른다.
- 토큰 만료를 대비한 자동 재발급 로직 없이는 장시간 무인 운영이 불가능하다.
- 재발급 자체가 실패할 때는 무한 재시도 대신 알림 후 중단하는 안전장치가 필요하다.
다음 글에서는 이렇게 발급받은 토큰으로 실제로 잔고와 계좌평가를 조회하는 흐름을 다룬다.
이 글은 키움증권이 공개한 개발자 문서 수준의 일반적인 인증 절차를 정리한 것이며, 실제 App Key·Secret·토큰 값이나 응답 데이터를 담고 있지 않습니다. 실제 연동은 반드시 키움증권 공식 API 문서를 기준으로 진행하시기 바랍니다. 이 글은 투자 조언이 아니며 특정 종목이나 매매기법을 추천하지 않습니다. 수익을 보장하지 않으며, 투자 손실에 대한 책임은 투자자 본인에게 있습니다.