본문 바로가기
WIKI 기술 지식 베이스

프록시

원문 보기 위키 갱신

프록시 (Proxying)

레거시 문서

출처: 문서

본문

레거시 문서

이 섹션은 레거시 플러그인 문서의 일부예요. 여기 설명된 프록시 구성과 사용은 이전 및 새 백엔드 시스템 모두에 적용돼요. 백엔드 플러그인과 모듈 만들기는 Building Backend Plugins and Modules를 참고하세요.

이 페이지는 Backstage 백엔드에서 내장 HTTP 프록시 기능을 구성하고 사용하는 방법을 설명해요.

개요

Backstage 백엔드에는 기본 HTTP 프록시가 패키지로 포함되어 있으며, 프론트엔드 플러그인 코드에서 백엔드 서비스 API에 도달하는 데 도움이 될 수 있어요. 프록시가 API와 통신할 때 가장 좋은 선택이 될 수 있는 시점에 대한 설명은 Call Existing API를 참고하세요.

시작하기

플러그인은 이미 기본 Backstage 프로젝트에 추가되어 있어요.

새 백엔드

프로젝트에 추가하려면 packages/backend/src/index.ts에 다음 줄을 추가하세요.

backend.add(import('@backstage/plugin-proxy-backend'));

이전 백엔드

packages/backend/src/index.ts에서:

backend.add(import('@backstage/plugin-proxy-backend'));

구성

프록시 플러그인에 대한 구성은 app-config.yaml 파일의 proxy 루트 키 아래에 위치해요.

예시:

# in app-config.yamlproxy:  reviveConsumedRequestBodies: true  endpoints:    /simple-example: http://simple.example.com:8080    '/larger-example/v1':      target: http://larger.example.com:8080/svc.v1      credentials: require      headers:        Authorization: ${EXAM...DER}        # ...or interpolating a value into part of a string,        # Authorization: Bearer ${EXAM...KEN}

프록시 구성 항목의 각 키는 프록시 플러그인이 마운트된 접두사 아래에서 일치시킬 라우트예요. 슬래시로 시작하지 않으면 자동으로 하나가 앞에 붙어요. 예를 들어 백엔드가 프록시 플러그인을 /proxy로 마운트하면, 위 구성은 /api/proxy/simple-example/... 및 /api/proxy/larger-example/v1/...에 대한 백엔드 요청에 프록시가 작동하게 해요.

각 라우트 안의 값은 단순한 URL 문자열이거나 http-proxy-middleware가 받아들이는 형식의 객체예요. 또한 다음 값을 가질 수 있는 선택적 credentials 키가 있어요.

  • require: 호출자는 각 요청에 Backstage 사용자 또는 서비스 자격 증명을 제공해야 해요. 자격 증명은 프록시 대상으로 전달되지 않아요. 이것이 기본값이에요.
  • forward: 호출자는 각 요청에 Backstage 사용자 또는 서비스 자격 증명을 제공해야 하며, 그 자격 증명은 프록시 대상으로 전달돼요.
  • dangerously-allow-unauthenticated: 이 프록시 대상에 접근하는 데 Backstage 자격 증명이 필요하지 않아요. 대상은 여전히 자체 자격 증명 검사를 적용할 수 있지만, 프록시는 Backstage의 인가를 받지 않은 호출자를 차단하는 데 도움이 되지 않아요. 또한 엔드포인트 구성에 allowedHeaders: ['Authorization']를 추가하면 Backstage 토큰(제공된 경우)이 전달될 거예요.

backend.auth.dangerouslyDisableDefaultAuthPolicy가 true로 설정되어 있으면 credentials 값이 적용되지 않는다는 점을 주의하세요. 모든 엔드포인트가 dangerously-allow-unauthenticated로 설정된 것처럼 프록시가 작동할 거예요.

값이 문자열이면 다음에 해당하는 것으로 가정돼요.

target: <the string>changeOrigin: truepathRewrite:  '^<url prefix><the string>/': '/'credentials: require

대상이 객체일 때는 편의를 위해 다음 주의 사항을 제외하고는 http-proxy-middleware에 있는 그대로 주어져요.

  • changeOrigin이 지정되지 않으면 true로 설정돼요. 이것은 가장 흔하게 유용한 값이에요.
  • pathRewrite가 지정되지 않으면 전체 접두사와 라우트를 제거하는 단일 재작성으로 설정돼요. 위 예시에서 '^/api/proxy/larger-example/v1/': '/' 재작성이 추가돼요. 즉 /api/proxy/larger-example/v1/some/path에 대한 요청이 http://larger.example.com:8080/svc.v1/some/path에 대한 요청으로 변환될 거예요.
  • credentials가 지정되지 않으면 require로 설정돼요.

추가 설정도 있어요.

  • allowedMethods: 전달되는 HTTP 메서드를 제한해요. 예를 들어 allowedMethods: ['GET']은 읽기 전용 접근을 강제해요.
  • allowedHeaders: 대상으로 전달되고 대상에서 받아야 하는 헤더 목록.

기본적으로 프록시는 안전한 HTTP 요청 헤더만 대상으로 전달해요. 이것들은 CORS에 안전한 것으로 간주되는 헤더에 기반하며 content-type이나 last-modified 같은 헤더와 프록시가 설정하는 모든 헤더를 포함해요. 프록시가 authorization 같은 다른 헤더를 전달해야 한다면 allowedHeaders 구성으로 활성화되어야 해요. 예를 들어 allowedHeaders: ['Authorization']이에요. 이는 cookie, X-Auth-Request-User 같은 기밀 헤더를 실수로 서드파티에 전달하지 않도록 도와줘야 해요.

같은 로직이 대상에서 프론트엔드로 다시 전송되는 헤더에도 적용돼요.

POST 요청 본문 전달

프록시가 대상으로 전달하는 요청 본문이 누락되는 문제를 해결하려면 proxy.reviveConsumedRequestBodies: true를 설정해 http-proxy-middleware의 fixRequestBody 핸들러가 사용되게 하세요.

이 경우 Content-Type 헤더를 application/json 또는 application/x-www-form-urlencoded로 설정하는 것을 기억하세요.

프록시 엔드포인트 확장 포인트

프록시 플러그인은 또한 위에서 설명한 것처럼 페이로드가 app-config에 정확히 지정된 추가 엔드포인트를 프로그래밍 방식으로 등록하기 위해 프록시 플러그인 모듈이 활용할 수 있는 proxyEndpointsExtensionPoint를 지원해요. app-config에서 구성된 엔드포인트는 항상 이런 방식으로 등록된 것들을 오버라이드한다는 점을 주의하세요.

모듈 패키지를 스캐폴딩하려면 yarn new를 실행하고 backend-module을 선택한 다음 proxy를 플러그인 ID로 프롬프트를 채우세요. 이렇게 하면 src/module.ts와 src/index.ts 파일이 있는 plugins/proxy-backend-module-<moduleId>가 생성돼요. 스캐폴딩된 패키지는 @backstage/backend-plugin-api에만 의존하므로, 확장 포인트를 제공하는 @backstage/plugin-proxy-node 패키지를 추가하세요.

yarn --cwd plugins/proxy-backend-module-demo-additional-endpoints add @backstage/plugin-proxy-node

그런 다음 생성된 src/module.ts를 아래 예시로 교체하세요.

plugins/proxy-backend-module-demo-additional-endpoints/src/module.ts

import { createBackendModule } from '@backstage/backend-plugin-api';import { proxyEndpointsExtensionPoint } from '@backstage/plugin-proxy-node/alpha';export const proxyModuleDemoAdditionalEndpoints = createBackendModule({  pluginId: 'proxy',  moduleId: 'demo-additional-endpoints',  register(reg) {    reg.registerInit({      deps: {        proxyEndpoints: proxyEndpointsExtensionPoint,      },      async init({ proxyEndpoints }) {        // Replace with however your setup obtains the credential.        const largerExampleAuth = 'Bearer <token>';        proxyEndpoints.addProxyEndpoints({          '/simple-example': 'http://simple.example.com:8080',          '/larger-example/v1': {            target: 'http://larger.example.com:8080/svc.v1',            credentials: 'require',            headers: {              Authorization: largerExampleAuth,            },          },        });      },    });  },});

plugins/proxy-backend-module-demo-additional-endpoints/src/index.ts

export { proxyModuleDemoAdditionalEndpoints as default } from './module';

그런 다음 백엔드 진입점(보통 packages/backend/src/index.ts)에서 프록시 플러그인과 함께 모듈을 설치하세요.

packages/backend/src/index.ts

backend.add(import('@backstage/plugin-proxy-backend'));backend.add(  import('@internal/plugin-proxy-backend-module-demo-additional-endpoints'),);

더 알아보기 (Learn more)