Fri Jan 09 2026
...
์นํ ๋ณด์ ์ ๋ฐ์ดํธ
์๋ก์ด ์
์ด์ ์๋ ๋ค๋ฅธ ํ๋ซํผ์ ๋นํด ์นํ ์ค์ ์ ์ถ๊ฐ์ ์ธ ๋ง์ฐฐ์ด ์์์ต๋๋ค. ์ฐ๋ฆฌ๋ ์ด๊ฒ์ด ์๊ตฌ๋๋ ์ถ๊ฐ ๋ณด์ ์กฐ์น ๋๋ฌธ์ ์ข์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ์ง๋ง, ์ต๊ทผ์ ๋ณด์์ด ์ ํ ์ฌํญ์ธ ๊ฒ๊ณผ ๋์ผํ๊ฒ ์์ ํ ๋ฉ์ปค๋์ฆ์ ๋ง๋ จํ์ต๋๋ค.
์ด์ ๋์
์ด์ ์๋ ์์คํ ์ด API ํค๋ฅผ ํ์ด๋ก๋์ ์ ๋ฌํ๊ณ ์ด๋ฅผ ๊ฒ์ฆํ ๊ฒ์ผ๋ก ๊ธฐ๋ํ์ต๋๋ค. ์ ํจํ์ง ์์ API ํค์ ๋ํด 401์ ๋ฐํํ์ง ์์ผ๋ฉด ์์คํ ์ ์ค์ ์ ํ์ฉํ์ง ์์์ต๋๋ค.
์๋ก์ด ๋์
์ด์ ์์คํ ์ ์๋ก์ด ์นํ ๊ตฌ์ฑ์ ์ํด API ํค๋ฅผ ์ ๋ฌํ์ง ์์ต๋๋ค. ๋์ , ์๋ก์ด ํตํฉ ๋ฐ ๊ธฐ์กด ํตํฉ์ ๋ํด ์๋ช ๋ HMAC ์๋ช ์ด ํฌํจ๋ฉ๋๋ค. ํ์ํ ๋ณด์ ์์ค์ ๋ฐ๋ผ ์ด ์๋ช ์ ๊ฒ์ฆํ ์๋, ํ์ง ์์ ์๋ ์์ต๋๋ค.
๊ธฐ์กด ๊ตฌ์ฑ์ ๊ณ์ํด์ API ํค๋ฅผ ์ ๋ฌํฉ๋๋ค - ์ด์ ์ง์ ํฐ์ผ์ ํตํด ์ด๋ฅผ ๋ ์์ฒญํ ์ ์์ต๋๋ค.
HMAC ์๋ช ๊ฒ์ฆ
FastComments๋ ์ด์ ๋ชจ๋ ์นํ ์์ฒญ์ ๋ค์ ํค๋๋ฅผ ์ ์กํฉ๋๋ค:
| ํค๋ | ์ค๋ช |
|---|---|
X-FastComments-Timestamp |
์์ฒญ์ด ์๋ช ๋ Unix ํ์์คํฌํ(์ด) |
X-FastComments-Signature |
sha256=<hex> ํ์์ HMAC-SHA256 ์๋ช
|
token |
๊ทํ์ API ๋น๋ฐ(ํ์ ํธํ์ฑ์ ์ํด ์ ์ง) |
์๋ช ์ ๊ณ์ฐํ๋ ๋ฐฉ๋ฒ
- ์ฐ๊ฒฐ:
timestamp + "." + JSON_payload_body - API ๋น๋ฐ์ ํค๋ก ์ฌ์ฉํ์ฌ HMAC-SHA256 ๊ณ์ฐ
- ๊ฒฐ๊ณผ๋ฅผ 16์ง์๋ก ์ธ์ฝ๋ฉ
์์ ๊ฒ์ฆ (Python)
import hmac
import hashlib
import time
import json
def verify_webhook_signature(headers, body, api_secret):
timestamp = headers.get('X-FastComments-Timestamp')
signature = headers.get('X-FastComments-Signature')
if not timestamp or not signature:
return False
# ์ต๊ทผ ํ์์คํฌํ ๊ฒ์ฆ
now = int(time.time())
if abs(now - int(timestamp)) > 300:
return False
# ์๋ช
๊ฒ์ฆ
payload = json.dumps(body, separators=(',', ':'))
message = f"{timestamp}.{payload}"
expected = hmac.new(
api_secret.encode(),
message.encode(),
hashlib.sha256
).hexdigest()
return signature == f"sha256={expected}"
HTTP ๋ฉ์๋ ์ ํ
๋ํ, ์ด๋ฒ ์ ๋ฐ์ดํธ์ ํจ๊ป ๊ฐ ์นํ ์ด๋ฒคํธ ์ ํ์ ๋ํด HTTP ๋ฉ์๋๋ฅผ ๊ตฌ์ฑํ ์ ์์ต๋๋ค:
- ์์ฑ ์ด๋ฒคํธ: POST ๋๋ PUT (๊ธฐ๋ณธ๊ฐ: PUT)
- ์ ๋ฐ์ดํธ ์ด๋ฒคํธ: POST ๋๋ PUT (๊ธฐ๋ณธ๊ฐ: PUT)
- ์ญ์ ์ด๋ฒคํธ: DELETE, POST ๋๋ PUT (๊ธฐ๋ณธ๊ฐ: DELETE)
๋ณด์ ์ด์
์ ์์คํ ์ ๋ช ๊ฐ์ง ์ด์ ์ด ์์ต๋๋ค:
- ์ค๊ฐ์ ๊ณต๊ฒฉ์ ๋ํ ๋ณดํธ
- ํ์์คํฌํ ๊ฒ์ฆ์ ํตํ ์ฌ์ ์ก ๊ณต๊ฒฉ ๋ฐฉ์ง
- ํ์ด๋ก๋ ๋ณ์กฐ ๊ฐ์ง
ํ์ ํธํ์ฑ
API ๋น๋ฐ์ ํฌํจํ๋ token ํค๋๋ ์ฌ์ ํ ๋ชจ๋ ์์ฒญ๊ณผ ํจ๊ป ์ ์ก๋ฉ๋๋ค. ๊ธฐ์กด ํตํฉ์ ์์ ์์ด ๊ณ์ ์๋ํ๋ฉฐ, ์์ ์ธ๊ธํ ๋๋ก ๊ตฌ์ ๋์์ ๋ ์์ฒญํ ์ ์์ต๋๋ค.
๋ฌธ์
์์ ํ ๋ฌธ์๋ ์ฐ๋ฆฌ์ ์นํ ๊ฐ์ด๋๋ฅผ ์ฐธ์กฐํ์ธ์.
๊ฒฐ๋ก
๋ชจ๋ ์ฃผ์ ๋ฆด๋ฆฌ์ค์ ๋ง์ฐฌ๊ฐ์ง๋ก, ์ฐ๋ฆฌ๋ ์ด๋ฌํ ๋ณ๊ฒฝ ์ฌํญ์ ์ต์ ํํ๊ณ ํ ์คํธํ๋ฉฐ ์ ์ ํ ๋ฆด๋ฆฌ์คํ ์ ์์ด์ ๊ธฐ์ฉ๋๋ค. ๋ฌธ์ ๊ฐ ๋ฐ๊ฒฌ๋๋ฉด ์๋์ ์๋ ค์ฃผ์ธ์.
๊ฐ์ฌํฉ๋๋ค!
