
๐ bingbot์ผ๋ก ์ธํ ์๋ชป๋ API ์์ฒญ ์ฐจ๋จํ๊ธฐ
๋ฌธ์ ๋ฐ๊ฒฌ
ํด์ธ TNA ์๋น์ค๋ด DataDog ๋ชจ๋ํฐ๋ง์์ /analytics ์๋ํฌ์ธํธ์ ๋ํ 500์๋ฌ๊ฐ ์ง์์ ์ผ๋ก ๋ฐ์ํ๊ณ ์์์ต๋๋ค. ๋ฌธ์ ๋ POST ๋ฉ์๋๋ง ํ์ฉํ๋ ์๋ํฌ์ธํธ์ GET ์์ฒญ์ด ๋น๋ฒํ๊ฒ ๋ค์ด์ค๊ณ ์๋ค๋ ์ ์
๋๋ค.
์์ธ ํ์
์ ํ๋ฆฌ์ผ์ด์ ๊ด์ ์์๋ ์ ์์ ์ธ ์ฌ์ฉ์ flow์์๋ ์ ๋ ๋ฐ์ํ์ง ์๋ ์์ฒญ์ด์๊ธฐ์ ํฌ๋กค๋ฌ์ ์ํ ๋น์ ์ ํธ๋ํฝ์ผ๋ก ์ง์ํ๊ณ DataDog๋ด User-Agent๋ฅผ ํ์ธํ ๊ฒฐ๊ณผ Microsoft Bing์ ๊ฒ์ ํฌ๋กค๋ฌ ๋ด์ด ์์ธ์ด์์ต๋๋ค.
xxx.xxx.xx.xxx - - [12/Dec/2025:07:24:52 +0000] "GET /analytics HTTP/1.1" 500 90 "-"
"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; bingbot/2.0;
+http://www.bing.com/bingbot.htm)"
ํ๋ก ํธ์๋ ์ฝ๋๋ฅผ ํ์ธํด๋ณด๋ `/analytics` ์๋ํฌ์ธํธ๋ ๋ช ์์ ์ผ๋ก POST ์์ฒญ์ผ๋ก๋ง ํธ์ถ๋๊ณ ์์์ต๋๋ค.
useEffect(() => {
async function fetchPostProductAnalytics() {
await postProductAnalytics(productId, {
url: `${process.env.NEXT_PUBLIC_WEB_BASE_URL}/tna/products/${productId}`,
})
}
fetchPostProductAnalytics()
}, [productId])
๊ทธ๋ ๋ค๋ฉด HTML ํ๊ทธ๋ ์๋๊ณ , ๋งํฌ๋ก ๋ ธ์ถ๋ ์ ๋ ์๋ ์ด ์๋ํฌ์ธํธ์ ์ GET ์์ฒญ์ด ๋ฐ์ํ์๊น์?
์ bingbot์ด API๋ฅผ ํธ์ถํ์๊น?
์กฐ์ฌ ๊ณผ์ ์์ ๋ ๊ฐ์ง ์ค์ํ ์ฌ์ค์ ํ์ธํ์ต๋๋ค.
- bingbot์ JavaScript๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ค.
- bingbot์ ๋จ์ํ HTML ๋งํฌ๋ง ์์งํ๋ ํฌ๋กค๋ฌ๊ฐ ์๋๋ผ, JavaScript ๋ฒ๋ค ํ์ผ์ ๋ค์ด๋ก๋ํ๋ฉฐ ํ์ด์ง ์ค์๋๋ ํ๊ฒฝ์ ๋ฐ๋ผ JavaScript๋ฅผ ์คํํด ๋ ๋๋งํ ์ ์์ต๋๋ค. ์ด ๊ณผ์ ์์ ๋ฒ๋ค ๋ด๋ถ์ ํฌํจ๋ API ๊ฒฝ๋ก๊ฐ ๋ ธ์ถ๋์ด ํฌ๋กค๋ง ๋์์ด ๋๊ฒ์ผ๋ก ๋ณด์ ๋๋ค. ์ค์ ๋ก ๋น๋๋ JavaScript ๋ฒ๋ค ํ์ผ์์ /analytics ๊ฒฝ๋ก๋ฅผ ์ง์ ํ์ธํ ์ ์์์ต๋๋ค.
f = async (e, t) => await i.be.post("/foo/bar/baz".concat(e, "/analytics"), t);
์ด ๊ณผ์ ์์ bingbot์ด JS ๋ฒ๋ค ๋ด ๋ฌธ์์ด์ ์ ์ ์ผ๋ก ๋ถ์ํ๊ฑฐ๋, JS๋ฅผ ์คํํ ๋ค /analytics ๊ฒฝ๋ก๋ฅผ ์์งํ๊ฒ์ผ๋ก ๋ณด์
๋๋ค.
- ํฌ๋กค๋ฌ๋ HTTP Method์ ์๋ฏธ๋ฅผ ๊ณ ๋ คํ์ง ์๋๋ค.
ํฌ๋กค๋ฌ๋ API์ ์คํ์ ์ดํดํ์ง ์๊ธฐ๋๋ฌธ์, URL์ ๋ฐ๊ฒฌํ๋ฉด ๊ธฐ๋ณธ์ ์ผ๋ก GET ์์ฒญ์ ์๋ํฉ๋๋ค. ๊ทธ ๊ฒฐ๊ณผ POST ์ ์ฉ API์์๋ GET ์์ฒญ์ด ๋ฐ๋ณต์ ์ผ๋ก ์ ์ ๋์๊ณ ์๋ฒ์ 500 ์๋ฌ๊ฐ ๋ฐ์ํ์ฃ .
๋์ ๋ถ์
- โ
์๋ฒ์์
405 METHOD_NOT_ALLOWED์ฒ๋ฆฌ
์ฅ์
- API ์คํ ๋ช ํํ (POST๋ง ํ์ฉ)
- ์๋ฌ ๋ก๊ทธ ๊ฐ๋ ์ฑ ํฅ์
๋จ์
- ์์ฒญ์ด ๋ฐฑ์๋๊น์ง ๋๋ฌ (๋ฆฌ์์ค ์๋ชจ)
- ํฌ๋กค๋ฌ ์์ฒญ ์์ฒด๋ฅผ ์ฐจ๋จํ์ง๋ ๋ชปํจ
- ํ๋ก ํธ middleware์์
/analyticsGET ์์ฒญ ์ฐจ๋จ
์ฅ์
- ๋ฒํฐ์ปฌ์์ ๋น ๋ฅธ ๋์ ๊ฐ๋ฅ
- ๋ถํ์ํ ํ๋ก์ ํธ๋ํฝ ๊ฐ์
๋จ์
- ์์ธ์ผ์ด์ค๊ฐ ๋์ด๋ ์๋ก ๋ฏธ๋ค์จ์ด ๋ก์ง ๋ณต์ก๋ ์ฆ๊ฐ
web/api gateway๋ด ๊ฒฝ๋ก๋ณ ์ ํ
์ฅ์
- ์ค์ ์ง์ค์ ๊ด๋ฆฌ
- ์ฌ๋ฌ ์๋น์ค์ ์ผ๊ด๋ ์ ์ฑ ์ ์ฉ ๊ฐ๋ฅ
๋จ์
- ๋ค๋ฅธ ๋ฒํฐ์ปฌ์์ ๋์ผ ๊ฒฝ๋ก ์ฌ์ฉ๊ฐ์ผ์ฑ ์กด์ฌ
- ์ํฅ ๋ฒ์ ๋ถ์ ํ์
- โ WAF(Web Application Firewall): ๋คํธ์ํฌ ๋ ๋ฒจ ์ฐจ๋จ
์ฅ์
- ๊ฐ์ฅ ์๋จ์์ ์ฐจ๋จํ์ฌ ๋ฆฌ์์ค ์ต๋ ์ ์ฝ
- ํ๋ก ํธ/๋ฐฑ์๋ ๋ฆฌ์์ค ์ ์ฝ
- ์ธํ๋ผ ๋ ์ด์ด์์ ํ์คํ ๋ฐฉ์ด
๋จ์
- ์ธํ๋ผํ ํ์ ํ์
์ต์ข ์๋ฃจ์
๋ฐฑ์๋(1๋ฒ) + WAF(4๋ฒ) ์กฐํฉ์ ์ ์ฉํ์ต๋๋ค.
- WAF: bingbot์ ๋คํธ์ํฌ ๋ ๋ฒจ์์ ์ฐจ๋จํ์ฌ ๋น์ ์ ์์ฒญ์ ๊ทผ๋ณธ์ ์ผ๋ก ์ฐจ๋จ
- ๋ฐฑ์๋: ์ถํ ๋์ผํ ํจํด์ ์์ฒญ์ด ๋ฐ์ํ๋๋ผ๋ 405 ์๋ต์ผ๋ก ์กฐ๊ธฐ ์๋ณ ๊ฐ๋ฅํ๋๋ก ๊ฐ์
๊ธฐ๋ ํจ๊ณผ
- DataDog๋ด ๋์ผ ์๋ฌ ๋ก๊ทธ ๋ํญ ๊ฐ์
- ๋ถํ์ํ ํธ๋ํฝ ์ ๊ฑฐ๋ก ์๋ฒ ๋ฆฌ์์ค ์ ์ฝ
- ๋คํธ์ํฌ -> ์ ํ๋ฆฌ์ผ์ด์ ๋ ๋ฒจ์ ๋ค์ธต ๋ฐฉ์ด ๊ตฌ์กฐ๋ก ์์ ์ฑ ํ๋ณด
๊ฒฐ๋ก
์ด๋ฒ ์ด์๋ฅผ ํด๊ฒฐํ๋ฉด์ ํฌ๋กค๋ฌ๊ฐ ๋จ์ํ HTML ๋งํฌ๋ง ์์งํ์ง ์๊ณ JavaScript ๋ฒ๋ค ํ์ผ์ ๋ถ์ํ๊ฑฐ๋ ์คํํ์ฌ URL์ ์ถ์ถํ๋ค๋ ์ ์ ๋ค์ ํ๋ฒ ํ์ธํ์ต๋๋ค. ๋ํ ๋ฒํฐ์ปฌ๋ด ๋ฌธ์ ๋ก๋ง ์น๋ถํ์ง ์๊ณ , ๋คํธ์ํฌ ๋ ๋ฒจ๋ถํฐ ์ ํ๋ฆฌ์ผ์ด์ ๋ ๋ฒจ๊น์ง ์ฌ๋ฌ ๋ฐฉ์ด์ ์ ๊ตฌ์ถํ๋ ๊ฒ์ด ์ด์ํ๊ฒฝ์์๋ ํจ์ฌ ์์ ์ ์ธ ์ ๊ทผ์ด๋ผ๋ ์ ์ ๋ฐฐ์ธ ์ ์์์ต๋๋ค.
์ฐธ๊ณ ์๋ฃ
- Bing Webmaster Guidelines - Bing ํฌ๋กค๋ฌ ๋์ ๋ฐฉ์
- bingbot Series: JavaScript, Dynamic Rendering, and Cloaking. Oh My! - Microsoft Bing Blogs
๋๊ธ