회고
[우테코] 24편 : 오픈미션 18일차
| 서론
안녕하세요 팡일입니다!
오늘은 우아한테크코스 8기 프리코스의 오픈미션 18일차 포스팅입니다. 오늘은 진행한 점들에 대해서 기록하고 공유하려고 합니다!
| 오늘 한 일
1) QA
QA 진행하기
받은 QA 정리하기
2) 리스트 페이지
내용 검색 기능 고민하기
3) 작성 페이지
마크다운 에디터 가이드라인 고민하기
감정 커스텀에 대해서 고민하기
글 별 카테고리 추가에 대해서 고민하기
마크다운 XSS 취약점 해결
4) 로그인 페이지
비밀번호 찾기 기능 고민하기
5) List 페이지
회고 카드에 카테고리까지 추가
6) Detail/Share 페이지
카테고리 항목 추가
카테고리, 감정 항목이 0개인 경우에 대한 문구 추가
| 어려웠던 점 & 배운 점
1) 점진적 기능 개발과 리팩터링의 중요성
(1) 어려웠던 점
: ‘카테고리’ 기능은 처음에는 단순히 회고에 태그를 추가하는 정도로 보였습니다. 하지만 실제 구현에 들어가 보니, UI 컴포넌트 개발, 전역 상태 관리 시스템 구축, 백엔드 데이터 모델 확장, Firestore 데이터 연동, 그리고 최종적으로 ListCard와 DetailCard 등 여러 화면에서의 UI 통합에 이르기까지 예상보다 훨씬 복잡한 작업들이 연쇄적으로 이어졌습니다. 초기 기획 단계에서는 이러한 다층 구조를 정확히 예측할 수 없었고, 한 레이어의 변경이 다른 레이어에 미치는 영향을 파악하는 데도 꽤 많은 시간이 필요했습니다.
(2) 배운 점
: 이를 통해 UI, 상태 관리, 데이터 연동, 버그 수정, 리팩터링 등 기능을 작고 명확한 단위로 나누어 개발하고 커밋하는 방식이 복잡한 기능을 체계적으로 완성하는 데 효과적이라는 점을 배웠습니다. 단계별로 분리하면 각 단계의 문제를 고립시켜 집중적으로 해결할 수 있었고, 기능 구현 이후에도 사용자 피드백과 자체 검토를 기반으로 ListCard의 카테고리 위치 조정, 빈 상태 메시지 추가 등 UI/UX 개선 작업이 자연스럽게 이어졌습니다. 이 경험을 통해 소프트웨어 개발은 한 번에 완성하는 작업이 아니라, 지속적인 개선을 통해 점진적으로 완성도를 높여가는 과정이라는 ‘진화하는 아키텍처’의 가치를 다시 한번 실감할 수 있었습니다.
2) 사용자 경험(UI/UX)을 고려한 디테일의 힘
(1) 어려웠던 점
: 카테고리 기능이 추가되었음에도 회고 목록 카드(ListCard)에서 카테고리 정보가 감정 칩과 스타일이 비슷해 시각적으로 눈에 잘 띄지 않았습니다. 이는 정보의 우선순위를 드러내는 시각적 계층화가 부족했던 때문이었죠. 또한 CategorySection과 EmotionSection에서도 사용자가 아무 것도 선택하지 않았을 때 해당 공간이 ‘선택하지 않은 상태’인지, ‘표시가 잘못된 것’인지 구분하기 어려웠습니다. 빈 상태를 명확히 안내해주는 UX 요소가 부족했던 것입니다.
(2) 배운 점
: 이를 개선하기 위해 ListCard에서 카테고리 앞에 # 심볼을 붙이고 날짜 정보와 함께 상단 우측에 배치해 메타 정보로서의 가시성을 크게 높였습니다. 작은 디자인 조정만으로도 정보 인식과 사용자 경험이 크게 달라질 수 있다는 점을 실감했습니다. 또한 detailMode일 때 CategorySection과 EmotionSection에 “선택된 카테고리가 없습니다.”, “선택된 감정이 없습니다.” 같은 안내 문구를 추가해, 사용자가 현재 상태를 직관적으로 이해하고 다음 행동을 예측할 수 있도록 만들었습니다. 단순하지만 핵심적인 UX 디테일의 중요성을 다시 한 번 느끼는 개선 작업이었습니다.
3) 보안 취약점(XSS)의 발견과 DOMPurify를 이용한 방어
(1) 어려웠던 점
: Svelte의 {@html} 지시어는 마크다운을 HTML로 직접 렌더링할 때 매우 유용하지만, 사용자 입력 값을 필터링 없이 그대로 출력하면 XSS 공격에 취약해진다는 것을 알게 되었습니다. 특히 인증이 없는 공유 페이지에서는 스크립트 삽입이 실제 피해로 이어질 수 있다는 점을 명확히 확인할 수 있었습니다. 마크다운의 다양한 표현력을 유지하면서도 script, onerror 같은 악성 코드를 필터링해야 한다는 점도 고민이었습니다. 단순히 모든 HTML을 막으면 기능과 사용자 경험이 저해되기 때문에 적절한 경계 설정이 필요했습니다. 여기에 SvelteKit이 SSR을 지원한다는 점도 문제였습니다. DOMPurify는 브라우저 API에 의존하기 때문에 서버 환경에서 바로 사용할 수 없었고, SSR 환경에서 코드가 실행되면 오류가 발생할 가능성이 있어 환경 분기가 필수적이었습니다.
(2) 배운 점
: 웹 개발에서 사용자 입력은 기본적으로 신뢰할 수 없다는 원칙을 다시금 깊이 이해했습니다. 보안은 기능 개발과 별개가 아니라 필수적으로 고려해야 하는 기본 요소임을 깨달았습니다. DOMPurify를 통해 script 태그, style 태그, onerror, onclick 등 잠재적으로 악의적인 요소를 자동으로 제거하면서도 마크다운의 서식 기능을 유지할 수 있음을 확인했고, 보안과 기능성을 모두 만족시킬 수 있는 좋은 접근이라고 느꼈습니다. 또한 SvelteKit의 browser 변수나 window 체크를 활용해 DOMPurify가 브라우저 환경에서만 실행되도록 분기하는 방어적 프로그래밍 패턴을 적용함으로써 SSR 환경에서 발생할 수 있는 런타임 오류도 방지할 수 있었습니다. 이 과정을 통해 XSS 방어는 한 번으로 끝나는 작업이 아니라, 새로운 기능 추가나 라이브러리 업데이트 때마다 반복적으로 검토해야 하는 중요한 유지보수 요소임을 명확히 인식하게 되었습니다.
| 내일 목표
1) 작성 페이지
마크다운 에디터 가이드라인 고민하기
감정 커스텀에 대해서 고민하기
2) 기타
도메인 구입하고 배포하기
미리보기 (OG) 개선하기
3) 리스트 페이지
카테고리 별 필터 추가하기
10개만 불러올 수 있는 기능 추가하기 (페이지네이션(?))
4) 공유 페이지
로그인한 상태에 대한 header, Options 개선하기
5) 기타
피드백을 받을 수 있는 통로 만들기
6) 오픈미션
제출물 정리하기
| 한 줄 회고
: "개선은 또 다른 개선을 낳는 법,, 열심히 해보자!"