Google 계정 로그인 연동 추가

This commit is contained in:
2026-07-29 14:02:07 +09:00
parent 99af25b8fa
commit 52ed053876
20 changed files with 897 additions and 9 deletions

View File

@@ -1,7 +1,7 @@
# 배포 가이드
> v1.11.0은 v1.10 개발 구간을 마감한 minor 릴리스다. 운영 배포 전 `068_csp_violation_aggregates.sql`, `069_media_catalog.sql`, `070_post_import_jobs.sql`을 순서대로 적용하고 미디어 카탈로그는 reconcile 완료 후 `MEDIA_CATALOG_MODE=database` 고정 순서를 지킨다. 게시물 Export·Import·일반 업로드는 디스크·임시 디렉터리 스트리밍을 사용하므로 NAS 앱 컨테이너의 임시 저장 공간과 `public/uploads/exports`, `public/uploads/_import-jobs` 쓰기 권한을 확인한다.
> 로컬 기준 v1.12.0에서 `npm run lint`, `npm test`, `npm run build`, `npm audit` 검증을 통과했다.
> v1.12.1은 Google 로그인/계정 연동을 추가한다. 운영 배포 전 `068_csp_violation_aggregates.sql`, `069_media_catalog.sql`, `070_post_import_jobs.sql`, `071_users_google_oauth.sql`을 순서대로 적용하고 미디어 카탈로그는 reconcile 완료 후 `MEDIA_CATALOG_MODE=database` 고정 순서를 지킨다. 게시물 Export·Import·일반 업로드는 디스크·임시 디렉터리 스트리밍을 사용하므로 NAS 앱 컨테이너의 임시 저장 공간과 `public/uploads/exports`, `public/uploads/_import-jobs` 쓰기 권한을 확인한다.
> 로컬 기준 v1.12.1에서 `npm run lint`, `npm test`, `npm run build`, `npm audit` 검증을 통과했다.
## 빌드 유형
@@ -14,7 +14,7 @@
> `npm run dev`는 프로젝트 전용 실행 스크립트를 통해 개발 서버, Admin, Tailwind Viewer 링크만 요약 출력한다.
## v1.11.0 배포 전 검증
## v1.12.1 배포 전 검증
Playwright API 테스트도 브라우저 바이너리는 필요하지 않지만 `verify:ci`에는 Chromium E2E가 포함된다. 최초 1회 의존성과 Chromium을 설치하고 Docker daemon이 실행 중인지 확인한다.
@@ -40,6 +40,8 @@ sh scripts/migrate-production-db.sh status
- `068_csp_violation_aggregates.sql`은 CSP 보고 집계 테이블을 만든다.
- `069_media_catalog.sql`은 미디어 카탈로그·참조·상태 계약을 만든다. 최초 상태는 `ready=false`이므로 마이그레이션 직후 곧바로 `MEDIA_CATALOG_MODE=database`만 켠 채 운영하지 않는다. 반드시 reconcile을 먼저 끝낸다.
- `070_post_import_jobs.sql`은 게시물 Import 작업/항목 상태 테이블을 만든다.
- `071_users_google_oauth.sql`은 회원 Google 로그인·계정 연동용 식별자 컬럼과 고유 인덱스를 만든다.
- 배포 직후(또는 `filesystem`) 상태에서 관리자 인증 후 `POST /admin/api/media/reconcile`을 1회 실행한다. 이 API는 파일을 삭제하거나 이동하지 않고 발견 파일 upsert, 참조 백필, 사라진 파일 `missing` 표시만 수행한다.
- `media_catalog_state`의 `ready=true`, 파일시스템/카탈로그 `count`와 `bytes` 일치, `staging`·`error` 행 0을 확인한다.
- 확인이 끝나면 운영 env를 `MEDIA_CATALOG_MODE=database`로 고정하고 재기동한다. 개발 환경도 동일하게 `database`로 고정한다. 준비 미완료·불일치·DB 조회 오류가 발생하면 애플리케이션은 자동으로 파일시스템 목록으로 fallback한다.
@@ -169,6 +171,8 @@ cp .env.example .env.production
# .env.production 파일에 운영 DB 연결 정보, 운영 전용 랜덤 비밀번호, APP_PORT=43080, DB_PORT=43081 입력
# 운영 DB에 owner/admin이 없으면 /admin/login에서 ADMIN_EMAIL/ADMIN_PASSWORD로 최초 owner 계정이 생성됨
# MEMBER_SESSION_SECRET은 ADMIN_PASSWORD와 다른 긴 난수 문자열로 반드시 입력
# Google 로그인을 사용하려면 GOOGLE_OAUTH_CLIENT_ID, GOOGLE_OAUTH_CLIENT_SECRET,
# GOOGLE_OAUTH_REDIRECT_URI=https://sori.studio/api/auth/google/callback 입력
# AdSense 통계를 대시보드에 연동하려면 GOOGLE_ADSENSE_CLIENT_ID, GOOGLE_ADSENSE_CLIENT_SECRET,
# GOOGLE_ADSENSE_REFRESH_TOKEN, GOOGLE_ADSENSE_ACCOUNT_NAME, GOOGLE_ADSENSE_CURRENCY_CODE를 추가로 입력
# Docker 네트워크 대역이 NAS 기존 컨테이너와 겹치면 DOCKER_SUBNET을 다른 사설 대역으로 변경
@@ -226,6 +230,23 @@ docker compose --env-file .env.production up -d
코드 변경 없이 `.env.production`만 수정했다면 `--build` 없이 `up -d`만으로 충분하다.
### Google 로그인 설정
Google 계정 로그인과 계정 연동을 사용하려면 Google Cloud Console의 OAuth 클라이언트에 아래 리다이렉트 URI를 등록한다.
- 로컬 개발: `http://127.0.0.1:43080/api/auth/google/callback`
- 운영: `https://sori.studio/api/auth/google/callback`
운영 `.env.production`에는 아래 값을 추가한다. AdSense와 같은 OAuth 클라이언트를 써도 되지만, 장기적으로는 로그인용 클라이언트를 별도로 두는 편이 관리하기 쉽다.
```bash
GOOGLE_OAUTH_CLIENT_ID=...
GOOGLE_OAUTH_CLIENT_SECRET=...
GOOGLE_OAUTH_REDIRECT_URI=https://sori.studio/api/auth/google/callback
```
관리자 Google 로그인은 자동으로 열리지 않는다. 먼저 기존 관리자 이메일/비밀번호로 로그인한 뒤 `/settings`에서 Google 계정을 연결해야 하며, 연결된 `owner` 또는 `admin` 계정만 `/admin/login`의 Google 로그인을 사용할 수 있다.
### AdSense refresh token 발급
AdSense Management API를 관리자 대시보드에서 조회하려면 OAuth 클라이언트 ID/시크릿 외에 1회 발급한 refresh token이 필요하다.