외부 API 연동 준비로 문답 신규 수십 건을 전수 검토했다. 기존에 파악한 것과 대조해 새 정보만 추리니 넷이 나왔다.
Table of contents
Open Table of contents
설정 — 서명 재료의 구조
인증에 전자서명이 필요한데 그 재료인 비밀값이 bcrypt 해시 형식이었다. 그냥 문자열이 아니라 $2b$ 버전과 코스트와 인코딩된 솔트가 $ 구분자로 이어진 구조를 갖고 있었다.
거기서 솔트 22자만 꺼내 16바이트로 디코딩해야 한다. 문자열 그대로 쓰거나 길이를 잘못 잡으면 서명이 다르게 나오고 인증이 실패한다.
주의 — 인코딩 방식의 두 글자
생성한 서명을 보낼 때 인코딩 방식이 갈렸다. 표준 base64로 보내면 검증에 실패하고 base64url로 보내야 성공한다.
둘의 차이는 +/와 -_ 문자 두 개인데 그것 때문에 인증 전체가 실패한다. 라이브러리 기본값이 표준인 경우가 많아서 명시적으로 고르지 않으면 놓치기 쉽다.
제약 — 앱 유형별 제한
호출 제한도 앱 유형에 따라 달랐다. 자체 스토어용 앱에는 속도 제한만 적용되고 대행이나 솔루션용 앱에는 총량 제한이 함께 붙는다.
그러면 속도 제한기 설계 자체가 달라진다. 앱 유형을 모르고 총량 관리를 넣으면 불필요한 복잡도가 되고 반대로 빼면 어느 날 갑자기 막힌다.
판단 기준 — 밀리초 경계와 절대값 고정
가장 미묘한 것이 변경분 조회의 시각 범위였다. 조회 상한 to가 주문의 paid_at과 정확히 같으면 그 주문이 누락된다는 경고가 문답에 있었다.
경계 처리가 미만이라 상한에 정확히 걸린 건이 안 들어온다. 이번 to를 다음 조회의 from으로 이어 붙이는 구조라면 그 건이 다음 조회에 들어오는지가 구현에 달려 있고 그래서 문서가 경고하는 것이다.
두 가지 방법이 있었는데 현재 시각을 그대로 상한으로 쓰는 것과 밀리초를 절대값으로 지정하는 것이다. 뒤쪽을 골랐다. 이유는 문답의 권장이고 상한을 해당 초의 .999로 끝까지 잡고 다음 구간을 다음 초의 .000부터 시작하면 빈틈도 겹침도 없어서다. 대신 조회 주기가 초 경계에 맞춰 살짝 늦어지는 것을 감수했다. 현재 시각을 그대로 쓰면 밀리초가 임의값이라 이 보장이 성립하지 않는다.
대응 — 상대 정책에 맞춘 연결 유지
마지막은 성격이 달랐다. HTTP 클라이언트의 Keep-Alive를 2초 이내로 둬야 하고 위반하면 연결이 끊긴다는 것이었다.
보통은 연결을 오래 유지하는 쪽이 성능에 좋은데 여기서는 반대로 재사용을 사실상 제한한다. 이것을 모르면 간헐적으로 연결이 끊기고 원인을 네트워크나 우리 코드에서 찾게 된다.
넷의 공통점이 있다. 어떻게 부르는지는 문서 본문에 있고 이렇게 하면 실패한다는 것은 문답에 있다. 그리고 넷 다 오류 메시지가 원인을 안 가리키는데 서명 실패는 인증 실패로만 나오고 주문 누락은 아무 오류도 안 나며 연결 끊김은 네트워크 오류처럼 보인다. 그것이 전수 검토가 필요한 이유였다.
정리
- 비밀값이 구조를 가진 형식이면 정확히 파싱한다
base64url인코딩을 명시적으로 고르고 기본값에 맡기지 않는다- 문자 두 개 차이가 인증 전체를 가른다
- 앱 유형에 따라 적용되는 제한 종류가 달라 설계가 달라진다
- 조회 상한이 대상 시각과 같으면 누락될 수 있다
- 밀리초를
.999와.000절대값으로 고정하면 빈틈도 겹침도 없다 Keep-Alive시간을 상대 정책에 맞추고 우리 최적화를 앞세우지 않는다- 오류 메시지가 원인을 안 가리키는 항목일수록 전수 검토가 필요하다