관리자 웹을 Android APK로 옮기기 — WebView 셸의 역할
운영자용 관리자 웹을 Android APK로 만들었습니다. 기존 화면을 WebView에서 열고, 휴대폰에서 필요한 이동·파일 선택·오류 처리를 작은 Java 앱에 붙이는 방식입니다.
이 글은 웹 개발자가 처음으로 운영자용 APK를 만드는 상황을 기준으로 썼습니다. 세 편에 걸쳐 구조 선택, 보안 경계, 빌드와 기기 검증을 정리합니다. 첫 번째 질문은 “어떻게 앱을 만들까”보다 “지금 앱이 맡아야 할 일이 무엇인가”였습니다.
관리 기능은 이미 웹에 있었습니다
기존 관리자는 React·Vite로 만든 웹이고, 업무 처리는 NestJS API가 담당합니다. 여러 서비스의 운영 기능이 이 관리자 아래에 모여 있습니다. 서비스 이용자용 화면과 운영자용 관리자는 서로 다른 화면과 계정을 사용합니다.
이번 요구는 이 관리자에 휴대폰으로 편하게 들어가 사용하는 것이었습니다. 같은 표와 입력 폼을 별도 모바일 화면으로 다시 만들면 웹과 앱 양쪽에서 변경을 따라가야 합니다. 우선 현재 기능을 재사용하고, 휴대폰에서 부족한 동작만 확인하는 편이 목적에 맞았습니다.
WebView는 앱 안에 놓는 웹 화면입니다
WebView는 Android 화면 안에서 웹 문서를 표시하는 구성 요소입니다. 완성된 브라우저처럼 주소창과 뒤로가기 버튼을 모두 제공하지는 않습니다. 그래서 페이지를 띄우는 일과, 사용자가 앱처럼 다룰 수 있게 만드는 일은 구분해야 합니다. 이 차이는 Android의 WebView 안내에도 설명되어 있습니다.
이번 앱에서는 MainActivity가 WebView와 상단 도구 모음, 진행 표시, 연결 실패 화면을 구성합니다. WebView에는 운영 HTTPS 주소를 고정했습니다. URL을 사용자가 입력하거나 외부 Intent로 자유롭게 바꾸는 브라우저는 만들지 않았습니다.
Android 앱
├─ Activity: 뒤로가기 · 새로고침 · 오류 안내
└─ WebView: 기존 React 관리자 화면
└─ 기존 API 요청
└─ NestJS: 인증 · 현재 관리자 권한 · 업무 처리
└─ 기존 데이터베이스
APK에 관리자 계정이나 API 비밀키를 넣지 않았습니다. 앱이 열리면 기존 로그인 화면을 거치며, 이후 할 수 있는 일도 서버가 가진 계정 권한에 따라 결정됩니다. 설치 파일을 받았다는 사실 자체는 접근 권한이 아닙니다.
다른 방법과 비교하면 선택 이유가 보입니다
| 방법 | 주로 재사용하는 것 | 이번 요구에서 고려한 점 |
|---|---|---|
| 모바일 웹·PWA | 기존 웹 화면 | 설치 파일 없이 접근 가능 |
| WebView APK | 기존 웹과 API | 작은 Android 셸 추가 |
| 네이티브·React Native | 주로 API와 업무 규칙 | 모바일 화면 별도 구현 |
WebView가 모든 앱에 더 좋은 방식이라는 뜻은 아닙니다. 오프라인 입력, 백그라운드 동기화, 푸시 알림, 카메라 중심 작업이 핵심이면 네이티브 기능에 더 많은 책임을 주어야 합니다. 지금은 온라인으로 관리 화면을 사용하는 것이 중심이어서 셸을 작게 유지했습니다.
개인이나 소수 운영자가 시험하는 단계에서는 APK를 직접 전달하는 경로도 사용할 수 있습니다. 다만 공개 스토어 배포를 끝낸 상태와는 다릅니다. 스토어 등록과 운영자에게 설치 파일을 전달하는 것은 이후 검토 범위가 다른 작업입니다.
웹과 Android 사이에는 연결해야 할 동작이 있습니다
뒤로가기 버튼은 WebView의 이동 이력을 확인합니다. 새로고침과 연결 재시도도 넣었습니다. 인터넷이 끊겼을 때 흰 화면만 남기지 않고, 사용자가 무엇을 해야 하는지 안내하는 데 필요한 기능입니다.
파일 입력도 별도 연결이 필요합니다. 웹의 파일 선택 요청을 Android 선택 화면으로 전달하고 결과를 다시 WebView에 넘깁니다. JavaScript의 확인·취소 대화상자 역시 Android 대화상자와 연결했습니다. 이 연결은 구현했지만, 모든 휴대폰에서 사진 선택과 실제 업로드까지 검증했다는 의미는 아닙니다.
지원하기 어려운 기능에는 돌아갈 길을 두었습니다. 현재 Blob으로 생성하는 파일 내보내기는 앱 안에서 완성하지 않았습니다. 상단의 ‘브라우저에서 열기’를 이용하도록 안내합니다. 앱의 WebView와 외부 브라우저는 로그인 상태를 공유한다고 가정할 수 없어 다시 로그인해야 할 수 있습니다.
웹 배포와 APK 배포의 경계를 나눴습니다
이번 앱은 관리자 웹의 JavaScript 파일을 APK 안에 묶어 넣지 않습니다. 서버에서 현재 웹 화면을 받아옵니다. 따라서 관리 메뉴나 표의 간격을 고친 경우에는 웹 배포 후 새 화면을 불러오면 반영됩니다. 실제로 모바일에서 상단 여백이 좁았던 문제도 관리자 웹의 레이아웃에서 수정했습니다.
반면 파일 선택 방식, Android 뒤로가기 처리, 네이티브 도구 모음, 앱 아이콘을 바꾸려면 새 APK가 필요합니다. 고정한 시작 도메인을 변경하는 경우도 여기에 해당합니다. “앱에 보이는 변경”이라는 이유만으로 모두 APK를 다시 만들 필요는 없고, 변경을 소유한 쪽을 먼저 확인하면 됩니다.
| 변경 | 반영 위치 |
|---|---|
| 메뉴·폼·표·모바일 여백 | 관리자 웹 |
| 계정 권한·업무 검증 | API와 데이터 |
| 파일 선택·앱 도구 모음 | Android APK |
| 오프라인·네이티브 푸시 | 추가 설계가 필요한 영역 |
첫 버전의 완료 범위를 작게 정했습니다
첫 버전은 인터넷 연결이 필요한 온라인 관리자 앱입니다. 별도 모바일 API, 네이티브 푸시, 오프라인 업무 처리는 포함하지 않았습니다. APK를 설치하고 로그인 화면을 열 수 있는 단계까지 확인했으며, 실제 휴대폰의 키보드·파일 선택·업로드는 별도 점검 항목으로 남겼습니다.
작은 앱을 만드는 일에서도 구현보다 범위를 정하는 일이 먼저였습니다. 웹의 책임을 유지하면서 Android가 꼭 필요한 부분만 맡게 하니, 다음에 무엇을 고쳐야 하는지도 분명해졌습니다. 다음 편에서는 이 구조에서 URL과 관리자 권한의 경계를 어떻게 지켰는지 정리합니다.
관련 글
관리자 WebView 보안 — URL 경계와 서버 권한을 함께 지키기
로그인이 필요한 관리자 웹을 WebView에 넣을 때 확인한 보안 경계를 정리했습니다. URL을 문자열로 비교하지 않는 이유, TLS 오류 차단, JavaScript와 네이티브 브리지의 차이, 파일 선택 제한을 설명합니다. 메뉴 표시와 별개로 서버가 현재 권한을 검사해야 하는 이유도 다룹니다.
PWA로 admin 페이지에 모바일 푸시 알림 붙이기
알림 하나 받자고 네이티브 앱을 만드는 건 오버킬이었습니다. 그래서 이미 쓰던 admin 웹앱에 PWA를 최소한으로 얹어 모바일 푸시 알림만 받기로 했습니다. iOS 설치형 제약과 푸시 전용 service worker, Slack fan-out까지 직접 부딪쳐 얻은 교훈을 담았습니다.
직접 구축한 개발 블로그의 '관리자 페이지', 서버에 올리지 않은 이유
직접 개발한 블로그의 관리자 페이지를 서버에 올리지 않고 운영하는 독특한 방식을 소개합니다. 개인적인 작업 환경과 효율성, 서버 비용 절감을 위한 저자의 이유를 자세히 알아보세요.