hello

ghost blog 버전을 6.x로 올리고 로그인이 안될 경우

환경 요약

  • Ghost 6.6.0 (Docker 컨테이너)
  • Cloudflare → Nginx Proxy Manager(NPM) → Ghost 컨테이너
  • staff device verification(장치 인증) 활성화 상태
    security.staffDeviceVerification: true
  • 메일(SMTP) 미설정 상태

증상 요약

  • /ghost/#/signin에서 비밀번호 입력 후 화면이 넘어가지 않거나,
  • 브라우저 콘솔에서 다음과 같은 에러:
    • GET /ghost/api/admin/users/me/?include=roles 403 (Forbidden)
  • Ghost 로그:
    • Authorization failed – Unable to determine the authenticated user or integration
    • Missing mail.from config, falling back to a generated email address
  • 브라우저 쿠키에 ghost-admin-api-session 이 생성되지 않음

근본 원인

  1. staffDeviceVerification = true 이면서 메일 설정이 없는 상태
    • Ghost 6.x는 security.staffDeviceVerification: true일 때
      새 기기/브라우저 로그인 시 이메일로 인증 코드를 보내야만 세션을 생성함.
    • 메일 설정이 없어서 인증 메일을 보낼 수 없고,
      그 결과 로그인 세션 쿠키(ghost-admin-api-session)가 만들어지지 않음.
    • 세션이 없으니 /ghost/api/admin/users/me 요청이 항상 403(Forbidden)으로 떨어짐.
  2. 메일 설정이 없을 때 나오는 Missing mail.from config 경고는
    단순 경고처럼 보이지만,
    staffDeviceVerification가 켜져 있으면 로그인 자체에 직격탄이 된다.

해결 방법

1) 임시 해결: staffDeviceVerification 비활성화

Docker 환경에서 다음과 같이 환경 변수를 추가한다.

environment:
  url: https://euno.blog
  security__staffDeviceVerification: "false"
  # ...
  • security__staffDeviceVerification: "false"
    → 내부적으로 security.staffDeviceVerification = false 로 적용.
  • 컨테이너 재시작 후에는 ghost-admin-api-session 쿠키가 정상 생성되고
    관리자 로그인이 정상 동작한다.

2) 정석 해결: 메일(SMTP) 설정 후 staffDeviceVerification 다시 켜기

메일이 실제로 발송되도록 SMTP 설정을 추가한다. 예:

environment:
  url: https://euno.blog

  mail__transport: "SMTP"
  mail__from: "Euno Blog <[email protected]>"
  mail__options__host: "smtp.example.com"
  mail__options__port: 587
  mail__options__secure: "false"
  mail__options__auth__user: "smtp-user"
  mail__options__auth__pass: "smtp-pass"

  security__staffDeviceVerification: "true"
  • 메일 발송이 정상 동작하는 것을 확인한 뒤
    security__staffDeviceVerification"true" 로 되돌리면
  • 새 기기 로그인 시 이메일로 장치 인증 코드를 받아 입력하는
    원래 의도된 2FA 흐름이 정상적으로 복구된다.

3) SMTP 계정 정보는 docker secret으로 관리 (선택)

민감한 값(auth__user, auth__pass)은 docker secret으로 주입하고,
컨테이너 내부 entrypoint에서 파일 내용을 읽어 환경변수로 export 하는 방식으로
보다 안전하게 관리할 수 있다.


정리

  • Ghost 6.x에서 security.staffDeviceVerification 을 켜면
    로그인 성공 = 이메일 인증 성공을 전제로 한다.
  • 메일이 설정되지 않으면 관리자 로그인이 403으로 막히며,
    이때의 핵심 징후는:
    • ghost-admin-api-session 쿠키가 생성되지 않는 것
    • /ghost/api/admin/users/me 403
  • 해결책은 둘 중 하나:
    1. 장치 인증 끄기: security__staffDeviceVerification: "false"
    2. SMTP 설정 후 다시 켜기: 메일 정상 발송 + security__staffDeviceVerification: "true"

이 포인트만 알고 있으면,
비슷한 구조(Cloudflare / NPM / Docker)에서 Ghost 로그인 403 문제를
매우 빠르게 판단하고 해결할 수 있다.