본문 바로가기
겪은 문제들

인코딩 키와 디코딩 키 중에 무엇을 써야할까?

by 가나무마 2024. 9. 7.
728x90

TL;DR

1. URL로 올 수 있는 문자는 ASCII 코드만 가능하다.
2. Retrofit, Ktor, Python Request 등 HTTP 라이브러리 대부분은 요청을 보낼 때 자동으로 퍼센티지 인코딩을 진행한다.
3. 따라서, 인코딩 키를 사용하면 두 번 인코딩 된 키가 서버로 전달된다.
4. 서버는 한 번만 디코딩하므로 키 불일치 발생

Encode Key Vs DECODE Key

공공데이터를 사용할 때, 인코딩키와 디코딩키를 주는 것을 볼 수 있습니다.
왜 키가 두개인지 이해가 안갔지만 이는 URI엔 아스키 코드만 사용 가능하기 때문입니다.

아스키코드 표

 
그러나, 우리들은 분명 아스키 코드에 속하지 않은 문자들이 URL에 사용되는 상황들을 종종 볼 수 있습니다.

위키 백과의 URL이 한글로 되어 있다.

 
그렇다면 이러한 URL들은 어떻게 사용하는 걸까요?
사실 실제로 우리가 이동한 URL은 아래와 같이 변환 과정을 거치고 서버에 전송됩니다.

# 우리가 입력하는 주소
https://ko.wikipedia.org/wiki/위키백과:대문 
# 실제로 서버가 받는 주소
https://ko.wikipedia.org/wiki/%EC%9C%84%ED%82%A4%EB%B0%B1%EA%B3%BC:%EB%8C%80%EB%AC%B8

'위키백과:대문'과 같은 아스키 문자에 속하지 않은 문자들이 아스키 코드로 변환됩니다.
 
실제로 URL 디코더 사이트에서 퍼센트가 들어간 문자열을 디코딩하면 원래 문자열이 나오는 것을 볼 수 있습니다.

문자열 디코딩 결과 사진 https://www.urldecoder.org/ko/

 
 
웹브라우저에선 URL에 아스키 코드가 아닌 문자열이 포함된다면 이 주소를 퍼센티지 인코딩을 통해 변환합니다. 그리고 변환된 주소를 통해 요청을 보냅니다. 이를 육안으로 확인하고 싶다면 크롬 개발자 도구를 F12를 눌러서 켜고 네트워크에서 Request URL에서 헤더를 확인해봅시다. 나무위키 대문으로 요청을 보내지 않고 인코딩된 주소로 요청하는 것을 볼 수 있습니다.

 
서버에서는 인코딩 된 키를 디코딩해서 사용합니다. 
 

그래서 디코딩 키를 왜 쓰냐?

Retrofit이나 FastAPI의 대부분의 요청은 자동으로 인코딩을 진행합니다. 따라서, 인코딩 키를 입력하면 인코딩 키를 두 번 인코딩하는 결과가 발생합니다.
1. 인코딩 키를 입력
2. Retrofit이나 FastAPI 등의 라이브러리를 통해서 요청
3. 라이브러리에선 인코딩 키를 한 번 더 인코딩 
4. 두 번 인코딩 된 키가 만들어진다.
5. 클라이언트에서 서버에 요청
6. 서버는 두 번 인코딩 된 키를 한 번 디코딩
7. 키 불일치 발생
 
curl 명령어를 통해서 더 직관적으로 알 수 있습니다.

HOST_URL=요청주소
DECODE_KEY=디코딩키
ENCODE_KEY=인코딩키

# 인코딩 옵션 없이 인코딩 키로 요청을 보냈을 때
curl -G "${HOST_URL}"\
	-d "serviceKey=${ENCODE_KEY}"\
	--data-urlencode "pageNo=1"\
	--data-urlencode "numOfRows=1"
# 인코딩이 이미 되어 있으므로 정상적으로 응답을 받는다.

# 인코딩 옵션을 걸고 인코딩 키로 요청을 보냈을 때
curl -G "${HOST_URL}"\
	--data-urlencode "serviceKey=${ENCODE_KEY}" \
	--data-urlencode "pageNo=1"  \
	--data-urlencode "numOfRows=1"
# 인코딩이 2번 진행되므로 응답 키가 존재하지 않는다는 응답이 온다.


# 인코딩 옵션 없이 디코딩 키로 요청을 보냈을 때
curl -G "${HOST_URL}"\
	"serviceKey=${DECODE_KEY}" \
	--data-urlencode "pageNo=1"   \
	--data-urlencode "numOfRows=1"
# 키가 등록 되어 있지 않다고 응답을 보낸다. 

# 인코딩 옵션을 걸고 디코딩 키로 요청을 보냈을 때
curl -G "${HOST_URL}"\
	--data-urlencode "serviceKey=${DECODE_KEY}" \
	--data-urlencode "pageNo=1"   \
	--data-urlencode "numOfRows=1"
# 인코딩 된 키값을 보내므로 정상적인 응답 성공

 
사용된 API 주소: https://www.data.go.kr/iim/api/selectAPIAcountView.do
 
참고자료
https://www.youtube.com/watch?v=lkAeX3T6A9I&ab\_channel=dcode

728x90
반응형