#2 - 가린 cURL이 그대로 실행되게, 토큰을 변수 자리로

마스킹과 플레이스홀더, safe/raw 단순화, IndexedDB 폐기, export↔import 대칭 — 더하기보다 빼기가 어려웠던 결정들

기능을 더하는 것보다 빼는 게 더 어려웠다. 2부는 만든 것보다, 의심하고 줄이고 들어낸 이야기에 가깝다.

무엇을 가릴 것인가

핵심 가치가 “안전한 공유"였으니, 화면에 보여줄 때도 변환할 때도 내보낼 때도 자동으로 가리게 했다. 가리는 대상은 둘이다. 하나는 자격증명으로 Authorization, Cookie, *-token, 그리고 쿼리의 token·key·password를 잡는다. 다른 하나는 본문에 섞여 있는 PII로, 신용카드 번호(Luhn으로 검증해 오탐을 줄이고 끝 4자리만 남긴다)·이메일·JWT·주민등록번호를 가린다. DevTools가 절대 대신 해주지 않는 영역이고, “토큰 유출 사고를 코드로 막는다"는 분명한 실무 가치가 있었다.

“근데 가리면 재현을 못 하잖아”

스스로 던진 이 질문이 제일 중요한 기능을 끌어냈다. 마스킹한 cURL은 안전하지만 Bearer ***MASKED***라 그대로 실행하면 401이다. 그래서 플레이스홀더 모드를 만들었다. 토큰 값은 지우되, 그 자리에 $AUTH_TOKEN(cURL)이나 {{AUTH_TOKEN}}(Postman) 같은 변수 자리를 남기는 것이다.

1
curl '...' -H "Authorization: Bearer $AUTH_TOKEN"

받는 사람은 자기 값만 채우면 바로 실행된다. 안전하면서도 재현이 되는, 둘 다 잡은 셈이다.

토글을 줄여 사고를 줄였다

처음엔 mask on/off와 placeholder on/off, 두 토글이 따로 있었다. 곧 사용자에게 네 가지 조합은 너무 많다는 걸 깨달았다. 특히 자격증명을 ***로만 내보내는 어중간한 조합은 거의 쓰이지 않았다. 그래서 변환·공유 모드를 원본과 안전(placeholder) 둘로 압축하고, *** 마스킹은 화면 표시와 본문 PII 전용으로만 남겼다. 토글 하나가 사라진 게 아니라, “공유용이냐 아니냐"라는 한 축으로 머릿속이 정리됐다.

DevTools랑 뭐가 다른지 정직하게 물었다

캡처·필터·cURL·HAR 같은 건 DevTools가 더 잘하거나 적어도 동급이다. 그건 인정했다. 대신 마스킹, 구조화된 export(Postman·문서), diff, 재전송 — 이쪽이 진짜 다른 점이라는 걸 분명히 하고 거기에 집중했다.

만들었다가 죽인 기능: IndexedDB 히스토리

“DevTools를 다시 열어도 이전 세션이 남아 있게” IndexedDB 영속을 넣었었다. 그런데 나중에 “처음엔 빈 화면으로 시작하고, import는 기존을 비우고 새로 채운다"로 UX를 정하자, 자동 영속이 갑자기 아무도 다시 읽지 않는 죽은 코드가 됐다. 그래서 idb 의존성까지 통째로 들어냈다. 저장과 복원은 세션 파일을 export하고 import하는 쪽으로 대체했는데, 오히려 명시적이고 파일로 백업·이동까지 된다. 코드는 줄고 동작은 더 정직해졌다.

나머지 결정들

export만 되고 import는 안 되던 비대칭도 없앴다. Postman Collection·HAR·세션 JSON 모두 왕복하게 했고, import는 파일 형식을 알아서 가려낸다. 마크다운 문서만 단방향인데, 요약본이라 본질적으로 되돌릴 수 없어서다.

DevTools 패널은 사이트가 열려 있어야 뜨는데, 남이 준 HAR을 그냥 열어 보는 데까지 DevTools를 강요하는 건 어색했다. 그래서 툴바 아이콘을 누르면 새 탭으로 뜨는 뷰어를 따로 뒀다. 실시간 캡처는 패널이, 파일 분석은 뷰어가 맡고 둘은 같은 코드를 공유한다.

돌아보면

워게임용 도구(인코더·해시·퍼저)까지 손이 뻗쳤을 때, 멈출 자리를 정했다. “한 가지를 잘하는 도구"에서 멀어지면 차별성보다 유지보수만 늘어난다. 넣을 수 있다고 다 넣지 않는 것도 설계라고 생각했다. 결국 2부 내내 한 일은 더하기보다 빼기였다 — 헷갈리는 토글을 줄이고, 죽은 코드를 들어내고, 늘리고 싶은 욕심에서 멈췄다.