Files
superport_v2/doc/backup/backend_change_requests.md

6.2 KiB

백엔드 수정 요청서 (2025-10-20 갱신)

1. 배경

  • 프런트엔드는 .env.development에서 API_BASE_URL=http://43.201.34.104:8080을 사용해 실서버 로그인 API를 호출한다.
  • 동일 API를 사용하는 운영 환경에서는 CORS 문제가 없지만, 로컬 웹 개발 시 브라우저가 http://localhost:<port> 오리진으로 사전 요청(preflight)을 보내면서 403 대신 CORS 차단이 발생한다.
  • 프런트(superport_v2)와 백엔드(superport_api_v2) 양쪽 구현을 재검토한 결과, 로그인 계약은 일치하나 실서버에서 CORS 응답 헤더가 전혀 내려오지 않는 것으로 확인되었다.
  • 로컬 개발 및 QA가 모두 실서버를 바라보고 있어, 백엔드에서 CORS 허용 정책을 명시적으로 정비해야 한다.

2. 현상 및 재현 절차

  • 브라우저 콘솔 오류:

    Access to XMLHttpRequest at 'http://43.201.34.104:8080/api/v1/auth/login' from origin 'http://localhost:50408'
    has been blocked by CORS policy: Response to preflight request doesn't pass access control check:
    No 'Access-Control-Allow-Origin' header is present on the requested resource.
    
  • curl 재현(사전 요청):

    curl -i -X OPTIONS \
      http://43.201.34.104:8080/api/v1/auth/login \
      -H 'Origin: http://localhost:50408' \
      -H 'Access-Control-Request-Method: POST'
    

    실제 응답: HTTP/1.1 404 Not Found + 헤더 없음 → CORS 미적용.

  • 실제 요청도 동일하게 헤더가 비어 있음:

    curl -i -X POST \
      http://43.201.34.104:8080/api/v1/auth/login \
      -H 'Origin: http://localhost:50408' \
      -H 'Content-Type: application/json' \
      -d '{"identifier":"test","password":"test"}'
    

    응답: 401 Unauthorized 본문은 내려오지만 Access-Control-Allow-Origin 헤더가 없음.

3. 프런트/백엔드 로그인 계약 점검

  • 프런트 요청 구조
    • 경로: POST ${ApiRoutes.apiV1}/auth/login/api/v1/auth/login
    • 페이로드: { identifier, password, remember_me } (lib/features/auth/data/repositories/auth_repository_remote.dart:18)
    • 응답 파싱: { data: { access_token, refresh_token, expires_at, user, permissions[] } } (lib/features/auth/data/dtos/auth_session_dto.dart)
  • 백엔드 구현
    • 라우트: #[post("/login")] (backend/src/api/v1/auth.rs:17) → web::scope("/api/v1")
    • 요청 모델: LoginRequest { identifier: String, password: String, remember_me: bool } (backend/src/domain/auth.rs:9)
    • 응답 모델: AuthSessionResponse { data: AuthSessionData { ... } }
  • 계약 비교 결론
    • 필드 명/자료형 모두 일치, remember_me 기본값 및 데이터 매핑도 호환.
    • 로그인 자체는 401/403 흐름이 정상이나, 브라우저 오리진이 차단되어 요청이 전달되지 못함.

4. 근본 원인 분석

  • 백엔드 App::new() 정의는 build_cors(&config.cors) 미들웨어를 wrap하고 default_service에서 OPTIONS 가드를 204로 처리하도록 구현되어 있음 (backend/src/app/mod.rs:36-132).
  • config/default.toml[cors] 설정은 allowed_origins = []로 전체 허용이 기본이지만, 실제 운영 환경에서는 APP_ENV에 대응하는 설정 또는 환경 변수로 제한된 오리진만 등록한 것으로 추정된다.
  • 하지만 허용 목록에서 로컬 호스트가 빠진 경우라면 CORS 미들웨어가 403을 반환해야 하는데, 현재는 단순 404/401 응답으로 보아 미들웨어가 동작하지 않거나, 리버스 프록시/로드밸런서 구간에서 CORS 헤더가 삭제되고 있다.
  • 결과적으로 브라우저는 Access-Control-Allow-Origin을 받지 못하고 사전 요청 단계에서 차단된다.

5. 요청 사항

  1. 백엔드 Actix CORS 설정 재점검
    • build_cors가 실제 배포 바이너리에도 적용되는지 확인하고, 필요한 경우 Cors::default() 대신 Cors::permissive() 또는 allowed_origin_fn 로깅을 추가해 런타임에서 허용 여부를 추적한다.
    • supports_credentials()를 유지하면서도 최소 http://localhost 기반 개발 포트 전체를 허용하도록 allowed_origin_fn에서 와일드카드 검사를 추가하거나, 설정 파일에 와일드카드 표기를 허용하도록 개선한다.
      .allowed_origin_fn(move |origin, _| {
          if allow_all {
              return true;
          }
          if origin.as_bytes().starts_with(b"http://localhost") {
              return true;
          }
          allowed_list.iter().any(|allowed| allowed == origin)
      })
      
    • 운영 배포용 설정(APP_ENV=production)에도 cors.allowed_originshttps://{prod-domain} + http://localhost (또는 사내 VPN 도메인)을 명시한다.
  2. 리버스 프록시/로드밸런서 검증
    • Nginx/ALB 등 중간 계층이 OPTIONS 메서드를 백엔드로 전달하는지 확인하고, 차단 시 proxy_set_header Access-Control-Allow-Origin 등을 설정한다.
    • 모든 사전 요청이 최소 204 혹은 200과 함께 Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers를 반환하도록 보장한다.
  3. 로그인 핸들러 응답 헤더 확인
    • 인증 성공/실패 여부와 관계없이 Access-Control-Allow-Origin이 반드시 포함되도록 통합 테스트를 추가한다.
    • 예시: cargo test cors_allows_login_origin 형태의 통합 테스트에서 Origin: http://localhost:50408 헤더를 넣고 응답 헤더를 검증.

6. 검증 및 수용 기준

  • curl -X OPTIONScurl -X POST 재현 시 Access-Control-Allow-Origin: http://localhost:50408 헤더가 내려오고 브라우저 CORS 에러가 사라질 것.
  • flutter run -d chrome --web-port 50408에서 로그인 성공/실패 흐름이 정상 동작.
  • 백엔드 cargo fmt, cargo test 모두 통과.
  • stock_approval_system_api_v4.md 또는 운영 문서에 허용 오리진 정책 및 설정 방법을 명시.

7. 후속 조치

  • 백엔드 담당자가 실제 배포 서버의 환경 변수/리버스 프록시 설정을 확인 후 조치 내용을 공유.
  • 수정 배포 이후 프런트 팀이 실서버 연결 테스트를 수행하고, 필요한 경우 추가 허용 오리진 목록을 요청.