실무·
더원서울안과 홈페이지 리뉴얼
안과 홈페이지의 SEO 강화를 위한 리뉴얼 프로젝트
서버 이관을 처음으로 경험하게 된 값진 프로젝트였습니다.
이렇게 만들었습니다
와커스에 이직 후 처음으로 맡은 홈페이지 전면 리뉴얼 프로젝트입니다. 지금 the1seoul.com에서 운영 중이며, 아래는 그중 제가 맡은 부분입니다.
비밀번호 찾기는 원래 임시 비밀번호를 메일로 보내는 방식이었습니다. 하지만 사용자 입장에서 임시 비밀번호를 메일함에서 확인하고, 다시 사이트로 돌아와 로그인 후 비밀번호를 변경해야 한다는 번거로움이 있었습니다. 사용자 경험은 사이트 개발에 있어서 무엇보다 가장 중요한 부분이라고 생각합니다. 따라서 본인 확인 후 비밀번호를 즉시 재설정하는 방식으로 바꿔 임시 비밀번호에 의한 비밀번호 찾기 과정의 번거로운 구간을 없앴습니다.
기존에는 존재하지 않는 아이디로 로그인 시도를 할 때, "존재하지 않는 아이디입니다."와 같이 경고 문구가 보이고 있었습니다. 이와 같은 문구는 공격자의 아이디 무차별 대입으로, 어떤 아이디가 존재하거나 존재하지 않는지 알아낼 수 있는 보안상의 허점이었습니다. 따라서 로그인 시도에는 횟수 제한을 걸어 무차별 대입을 어렵게 했습니다. 또한 관리자 화면과 게시판 대시보드에서 접근 제어가 아예 빠진 경로들을 찾아서 아무나 접근하지 못하도록 보안에 신경을 썼습니다. 또한 파일을 업로드할 수 있는 기능이 존재하였는데, 파일의 크기가 어떻든 항상 업로드가 가능했던 문제가 있었습니다. 이는 파일이 업로드되는 동안 사용자에게 아무런 응답이 가지 않는 문제의 원인이었습니다. 따라서 파일의 업로드 크기를 제한하여 사용자 경험을 개선하였습니다.
이전 회사인 이파피루스에서 PDF 뷰어에 스크린리더 대응을 넣었던 웹 접근성 향상 경험이 여기서 다시 쓰였습니다. 접근성은 기능을 다 만든 뒤 덧붙이는 부가 기능이 아니라, 사용자 모두를 위해서 꼭 필요한 부분이라고 생각합니다.
새 서버는 Nginx · 프론트엔드(사용자 · 관리자 화면) · 백엔드 · Redis를 각각 컨테이너로 분리하고, Docker Compose로 정의한 전용 브리지 네트워크에 묶어 Nginx가 컨테이너 이름으로 각 서비스에 라우팅하도록 리버스 프록시를 구성했습니다. 블루-그린 배포로 새 컨테이너를 띄울 때도 같은 네트워크에 붙이기만 하면 됐고, 이 구조 위에서 무중단 배포도 자연스럽게 붙일 수 있었습니다. Kubernetes와 같은 인프라를 선택하기엔 리뉴얼 프로젝트의 스케일이 단일 서버에 머물렀기 때문에 오버엔지니어링을 피하기 위해 AWS의 Lightsail 서비스를 선택하였습니다.
게시판 글과 팝업 이미지는 레거시 서버에 쌓여 있었습니다. 업로드 파일 또한 레거시 서버의 컨테이너 볼륨에 존재하고 있었던 상태라 그 파일들을 레거시 서버에 그대로 두면 리뉴얼 홈페이지에서는 글은 보이는데 이미지만 찾지 못하는 상황이었습니다. 레거시 서버의 데이터와 실제 파일들을 새 서버의 DB와 도커 볼륨으로 옮기는 DB/파일 이관 과정까지 담당하였습니다.
SSL 인증서는 Let's Encrypt 인증 기관을 통해 발급받은 뒤 만료 전에 스스로 갱신되도록 스크립트를 만들어 두었습니다. SSL 인증서 발급 과정은 작업의 순서가 중요하였습니다. 인증서를 미리 준비해 두지 않고 도메인부터 넘기면 그 사이 방문자는 HTTPS에 대한 보안 경고 화면을 보게 됩니다. DB/파일 이관, 그리고 SSL 인증서 작업에서 되돌리기 어려운 일일수록 먼저 확인하고 진행해야 한다는 점을 배웠습니다.
질환 정보 페이지에는 저자 표시가 필요했는데, 개별 의료진이 건별로 검수했다는 근거가 없는 상태에서 "OOO 원장 감수"처럼 특정인을 지목하면 허위 표시가 됩니다. 대신 병원이라는 기관 단위로 저작 주체를 명시하여 사실과 다른 신호를 보내지 않도록 하였습니다.
관리자가 이 정보를 직접 다루는 SEO 설정 화면도 정비하였습니다. 화면 두 개에 걸쳐 있던 SEO 관련 설정을 한 곳으로 모으고, 실제로는 적용되지 않던 입력칸(코드가 참조하지 않거나 보안 위험이 있어 백엔드가 의도적으로 무시하던 값)을 걷어냈습니다. 정리 도중 일본어·중국어 SEO 설정이 실제 사이트가 쓰는 언어 코드와 달라 등록해도 반영되지 않던 버그도 함께 발견하여 수정하였습니다.
백엔드 API를 프론트엔드와 연동
제가 프로젝트에 투입되기 전에는 사이트에서 보이고 있던 모든 값들이 코드상에 하드코딩되어 있었습니다. 하드코딩을 모두 걷어내고, 팀원이 이미 구현해두었던 백엔드 API를 프론트엔드와 연동하였습니다.회원 인증을 처음부터 끝까지
회원가입 · 로그인 · 아이디/비밀번호 찾기 · 마이페이지 · 회원탈퇴에 이르는 인증 흐름 전반을 맡았고 네이버와 카카오 소셜 로그인까지 구현하였습니다.비밀번호 찾기는 원래 임시 비밀번호를 메일로 보내는 방식이었습니다. 하지만 사용자 입장에서 임시 비밀번호를 메일함에서 확인하고, 다시 사이트로 돌아와 로그인 후 비밀번호를 변경해야 한다는 번거로움이 있었습니다. 사용자 경험은 사이트 개발에 있어서 무엇보다 가장 중요한 부분이라고 생각합니다. 따라서 본인 확인 후 비밀번호를 즉시 재설정하는 방식으로 바꿔 임시 비밀번호에 의한 비밀번호 찾기 과정의 번거로운 구간을 없앴습니다.
공개된 사이트라서 더 신경 쓴 것
병원 홈페이지는 누구나 들어올 수 있고 데이터에는 환자의 정보들이 섞여 있습니다. 기능을 붙이면서 허술해 보이는 부분들을 견고히 하기 위해 노력하였습니다.기존에는 존재하지 않는 아이디로 로그인 시도를 할 때, "존재하지 않는 아이디입니다."와 같이 경고 문구가 보이고 있었습니다. 이와 같은 문구는 공격자의 아이디 무차별 대입으로, 어떤 아이디가 존재하거나 존재하지 않는지 알아낼 수 있는 보안상의 허점이었습니다. 따라서 로그인 시도에는 횟수 제한을 걸어 무차별 대입을 어렵게 했습니다. 또한 관리자 화면과 게시판 대시보드에서 접근 제어가 아예 빠진 경로들을 찾아서 아무나 접근하지 못하도록 보안에 신경을 썼습니다. 또한 파일을 업로드할 수 있는 기능이 존재하였는데, 파일의 크기가 어떻든 항상 업로드가 가능했던 문제가 있었습니다. 이는 파일이 업로드되는 동안 사용자에게 아무런 응답이 가지 않는 문제의 원인이었습니다. 따라서 파일의 업로드 크기를 제한하여 사용자 경험을 개선하였습니다.
캡차를 활용한 웹 접근성 향상
아이디 · 비밀번호 찾기에는 캡차가 있는데, 눈으로 읽어야만 통과할 수 있었습니다. 하지만 안과 홈페이지에서 시력이 나쁜 사람이 계정을 못 찾는 상황이 될 수 있어 캡차의 음성 듣기 기능을 추가하여 접근성을 향상시켰습니다.이전 회사인 이파피루스에서 PDF 뷰어에 스크린리더 대응을 넣었던 웹 접근성 향상 경험이 여기서 다시 쓰였습니다. 접근성은 기능을 다 만든 뒤 덧붙이는 부가 기능이 아니라, 사용자 모두를 위해서 꼭 필요한 부분이라고 생각합니다.
옛 서버에서 새 서버로 옮기기
리뉴얼은 코드를 새로 쓰는 것으로 끝나지 않았으며 실제로 운영 중인 사이트의 인프라를 옮기는 일까지 맡았습니다.새 서버는 Nginx · 프론트엔드(사용자 · 관리자 화면) · 백엔드 · Redis를 각각 컨테이너로 분리하고, Docker Compose로 정의한 전용 브리지 네트워크에 묶어 Nginx가 컨테이너 이름으로 각 서비스에 라우팅하도록 리버스 프록시를 구성했습니다. 블루-그린 배포로 새 컨테이너를 띄울 때도 같은 네트워크에 붙이기만 하면 됐고, 이 구조 위에서 무중단 배포도 자연스럽게 붙일 수 있었습니다. Kubernetes와 같은 인프라를 선택하기엔 리뉴얼 프로젝트의 스케일이 단일 서버에 머물렀기 때문에 오버엔지니어링을 피하기 위해 AWS의 Lightsail 서비스를 선택하였습니다.
게시판 글과 팝업 이미지는 레거시 서버에 쌓여 있었습니다. 업로드 파일 또한 레거시 서버의 컨테이너 볼륨에 존재하고 있었던 상태라 그 파일들을 레거시 서버에 그대로 두면 리뉴얼 홈페이지에서는 글은 보이는데 이미지만 찾지 못하는 상황이었습니다. 레거시 서버의 데이터와 실제 파일들을 새 서버의 DB와 도커 볼륨으로 옮기는 DB/파일 이관 과정까지 담당하였습니다.
SSL 인증서는 Let's Encrypt 인증 기관을 통해 발급받은 뒤 만료 전에 스스로 갱신되도록 스크립트를 만들어 두었습니다. SSL 인증서 발급 과정은 작업의 순서가 중요하였습니다. 인증서를 미리 준비해 두지 않고 도메인부터 넘기면 그 사이 방문자는 HTTPS에 대한 보안 경고 화면을 보게 됩니다. DB/파일 이관, 그리고 SSL 인증서 작업에서 되돌리기 어려운 일일수록 먼저 확인하고 진행해야 한다는 점을 배웠습니다.
SEO 강화
검색엔진은 페이지를 읽어도 어디가 병원 이름이고 어디가 주소인지 스스로 알지 못합니다. 병원 정보 · 진료 페이지 탐색경로 · 질환 정보 콘텐츠에 구조화 데이터(JSON-LD)를 붙여 이를 검색엔진이 알아볼 수 있게 명시하였습니다.질환 정보 페이지에는 저자 표시가 필요했는데, 개별 의료진이 건별로 검수했다는 근거가 없는 상태에서 "OOO 원장 감수"처럼 특정인을 지목하면 허위 표시가 됩니다. 대신 병원이라는 기관 단위로 저작 주체를 명시하여 사실과 다른 신호를 보내지 않도록 하였습니다.
관리자가 이 정보를 직접 다루는 SEO 설정 화면도 정비하였습니다. 화면 두 개에 걸쳐 있던 SEO 관련 설정을 한 곳으로 모으고, 실제로는 적용되지 않던 입력칸(코드가 참조하지 않거나 보안 위험이 있어 백엔드가 의도적으로 무시하던 값)을 걷어냈습니다. 정리 도중 일본어·중국어 SEO 설정이 실제 사이트가 쓰는 언어 코드와 달라 등록해도 반영되지 않던 버그도 함께 발견하여 수정하였습니다.
