다음을 통해 공유


Azure Application Gateway에서 Web PubSub 서비스 사용

Azure Application Gateway는 애플리케이션 수준에서 작동하는 웹 트래픽 부하 분산 장치입니다. 웹 클라이언트에 대한 단일 연락 지점으로 사용할 수 있으며 다른 사람의 URI 경로와 같은 HTTP 특성에 따라 다양한 백 엔드로 웹 트래픽을 라우팅하도록 구성할 수 있습니다. Application Gateway는 WebSocket에 대한 기본 지원을 제공합니다. 사용자는 WebSocket을 사용하도록 설정하기 위해 특별한 것을 구성할 필요가 없습니다.

이 가이드에서는 Azure Application Gateway를 사용하여 Web PubSub 리소스를 보안할 수 있는 방법을 보여 줍니다. Application Gateway에서 나오는 트래픽만 허용하고 Web PubSub 리소스에 대한 공용 트래픽은 사용하지 않도록 설정하여 더 높은 수준의 보안을 달성합니다.

다이어그램에 설명된 것처럼 Web PubSub 리소스에 대한 프라이빗 엔드포인트를 설정해야 합니다. 이 프라이빗 엔드포인트는 Application Gateway와 동일한 Virtual Network에 있어야 합니다.

Azure Application Gateway에서 Web PubSub를 사용하는 아키텍처 개요를 보여 주는 다이어그램입니다.

이 가이드에서는 단계별 접근 방식을 사용합니다. 먼저 Web PubSub 리소스에 대한 트래픽이 성공적으로 프록시될 수 있도록 Application Gateway를 구성합니다. 두 번째, Application Gateway에서 나오는 트래픽만 허용하도록 Web PubSub의 액세스 제어 기능을 적용합니다.

1단계: Web PubSub 리소스에 대한 트래픽을 프록시하도록 Application Gateway 구성

다이어그램은 1단계에서 달성할 작업을 보여 줍니다.

1단계: 트래픽 Web PubSub 리소스를 프록시하도록 Application Gateway 구성의 아키텍처 개요를 보여 주는 다이어그램.

Azure Application Gateway 인스턴스 만들기

Azure Portal에서 Azure Application Gateway를 검색하고 단계에 따라 리소스를 만듭니다. 주요 단계는 다이어그램에서 강조 표시되어 있습니다.

Application Gateway 리소스를 만드는 방법을 보여 주는 스크린샷 - 기본 사항

Azure 리소스가 서로 안전하게 통신하려면 Virtual Network가 필요합니다. Azure Application Gateway에는 작성했던 전용 서브넷이 필요합니다. 이 가이드를 위해 1단계에서 Azure Application Gateway 리소스는 트래픽을 공용 인터넷통해 Web PubSub 리소스로 전달합니다. 2단계에서는 Azure Application Gateway가 Virtual Network를 통해 안전하게 Web PubSub 리소스로 트래픽을 전달하도록 Web PubSub 리소스를 보관하는 다른 서브넷을 만듭니다.

Azure Application Gateway 구성

Azure Application Gateway를 구성하려면 세 가지 구성 요소가 필요합니다.

  • 프런트 엔드
  • 백 엔드
  • 라우팅 규칙

프런트 엔드는 Azure Application Gateway의 IP 주소입니다. Azure Application Gateway를 웹 클라이언트의 단일 연락 지점으로 사용하므로 이를 위한 공용 IP를 만들어야 합니다.

Application Gateway 리소스를 만드는 방법을 보여 주는 스크린샷 - 공용 IP 만들기

백 엔드는 Application Gateway 리소스가 트래픽을 보낼 수 있는 리소스입니다. 이 경우 하나의 대상인 Web PubSub 리소스가 있습니다. Azure Portal에서 이 가이드를 따르는 데 사용하려는 기존 Web PubSub 리소스의 호스트 이름을 찾습니다. xxxx.webpubsub.azure.com과 같이 표시되어야 합니다.

Application Gateway 리소스를 만드는 방법을 보여 주는 스크린샷 - 백 엔드 풀 만들기.

프런트 엔드와 백 엔드가 모두 설정되면 프런트 엔드와 백 엔드를 연결하는 회람 규칙을 구성해야 합니다. 회람 규칙은 Application Gateway에 트래픽을 라우팅하는 방법과 위치를 알려줍니다.

먼저 수신기를 설정합니다. 이 구성은 Application Gateway에 PORT 80에서 HTTP 트래픽을 수신 대기하도록 지시합니다.

Application Gateway 리소스를 만드는 방법을 보여 주는 스크린샷 - 회람 규칙, 수신기 만들기.

두 번째, 백 엔드 대상을 설정합니다. 앞서 만든 백 엔드 풀(Web PubSub 리소스)에 대한 백 엔드 대상을 구성합니다. 또한 Application Gateway가 트래픽을 전달하는 방법을 지정해야 합니다. 백 엔드 설정을 통해 수행합니다.

Application Gateway 리소스를 만드는 방법을 보여 주는 스크린샷 - 회람 규칙, 백 엔드 대상 만들기.

Web PubSub 서비스는 HTTPs 트래픽만 허용합니다. 따라서 Application Gateway가 HTTPs를 사용하여 Web PubSub와 통신하도록 지시합니다. 이 가이드에 중점을 두기 위해 Application Gateway에서 호스트를 선택할 수 있도록 합니다. 프로덕션에서 사용자 지정 도메인을 설정하는 것이 좋습니다.

Application Gateway 리소스를 만드는 방법을 보여 주는 스크린샷 - 회람 규칙, 백 엔드 설정 만들기.

세 가지 구성 요소가 구성되면 스크린샷과 같은 항목이 표시됩니다. 다음과 같이 Application Gateway를 통해 트래픽 흐름을 시각화할 수 있습니다.

  1. 웹 클라이언트는 Application Gateway 리소스의 공용 IP로 요청을 보냅니다.
  2. Application Gateway는 사용자가 구성한 회람 규칙을 참조하여 트래픽을 라우팅합니다.
  3. 회람 규칙이 일치하면 트래픽이 지정된 백 엔드 대상으로 전달됩니다.

Application Gateway 리소스를 만드는 방법을 보여 주는 스크린샷 - 완료됨.

한 가지 강조할 점은 비WebSocket 연결을 정확히 동일한 방식으로 구성한다는 것입니다. Application Gateway의 WebSocket 연결 프록시에 대한 기본 지원에 대해 자세히 알아볼 수 있습니다.

마지막으로 업데이트해야 하는 것은 백 엔드 상태 프로브입니다. 설정 ->상태 프로브를 선택하고 생성된 상태 프로브 설정을 선택하고 경로를 /api/health 업데이트하고 다른 프로브를 변경하지 않고 유지합니다.

Application Gateway가 제대로 구성되었는지 테스트하고 확인합니다.

Web PubSub 리소스가 정상 상태인지 확인합니다.

Web PubSub 리소스의 잘못된 엔드포인트에 요청을 보내고 Web PubSub에서 오류 메시지를 예상합니다.

curl https://<your-web-pubsub-resource-endpoint>/client

"'hub'의 값이 잘못되었습니다."라는 오류 메시지가 표시됩니다. 이 오류는 Web PubSub 서비스가 요청을 성공적으로 수신하고 그에 따라 응답했음을 보여줍니다.

Application Gateway가 트래픽을 Web PubSub 리소스에 프록시하는지 확인합니다.

비슷한 단계를 반복하고 동일한 오류 메시지를 예상합니다.

curl http://<public-ip-of-your-application-gateway-resource>/client

"'hub'의 값이 잘못되었습니다."라는 동일한 오류 메시지가 표시됩니다. 이 오류는 Application Gateway 리소스가 구성된 회람 규칙을 사용하여 트래픽을 성공적으로 라우팅했음을 보여줍니다.

Application Gateway에서 WebSocket 연결을 프록시할 수 있는지 테스트하고 확인합니다.

Web PubSub를 통해 메시지 게시

주기적으로 Web PubSub를 통해 메시지를 게시하는 서버를 시뮬레이션하는 간단한 프로그램을 만듭니다. 1단계에서 프로그램을 로컬로 실행하여 모든 것이 작동되고 있는지 확인하고 2단계에서는 동일한 앱을 Azure App Service에 배포합니다.

폴더 구조 만들기
mkdir server && cd server
touch package.json && touch publish.js
소스 코드 복사

코드를 사용자가 만든 package.json 파일에 복사합니다.

{
  "scripts": {
    "start": "node ./publish.js"
  },
  "dependencies": {
    "@azure/web-pubsub": "^1.1.1",
    "express": "^4.19.2"
  }
}

코드를 사용자가 만든 publish.js 파일에 복사합니다.

const express = require("express")
// Uses the service SDK, which makes it easy to consume the capabilities of the service
const { WebPubSubServiceClient } = require('@azure/web-pubsub');

const app = express()
const PORT = 3000

// Hardcodes the hub name 
const hub = "myHub1";

// Grabs the connection string stored as an environment variable
let webpubsub = new WebPubSubServiceClient(process.env.WebPubSubConnectionString, hub);

// Serves the files found in the "public" directory  
app.use(express.static("public"))

// Returns Web PubSub's access token
app.get("/negotiate", async (req, res) => {
  let token = await webpubsub.getClientAccessToken()
  let url = token.url
  res.json({
    url
  })
}
// Every 2 seconds, we ask Web PubSub service to send all connected clients the message "hello, world"
setInterval(() => {
  webpubsub.sendToAll("hello, world", { contentType: "text/plain" });
}, 2000);

// Starts the server
app.listen(process.env.PORT || PORT, () => console.log(`server running on ${PORT}`));
종속성 설치 및 프로그램 실행

Azure Portal에서 Web PubSub 리소스의 connection string을 찾습니다. Web PubSub 리소스의 연결 문자열을 가져오는 방법을 보여 주는 스크린샷.

npm install

## Set environment variable
export WebPubSubConnectionString="<replace with the connection string of your Web PubSub resource>"

npm run start

콘솔에 "3000에서 실행 중인 서버"가 표시됩니다. 이 프로그램은 2초마다 Web PubSub 서비스에 연결된 모든 웹 클라이언트에 메시지를 브로드캐스트하도록 요청합니다. 현재 Web PubSub 리소스와 연결된 웹 클라이언트는 없지만 중요한 로깅을 실시간으로 모니터링할 수 있는 라이브 추적 도구 기능을 사용하도록 설정하여 이 흐름이 작동하는 것을 볼 수 있습니다.

브라우저에서 메시지 수신

브로드캐스트된 메시지를 받지 못하면 조명이 켜지지 않습니다. 이전에 만든 서버 폴더 내에서 클라이언트 코드를 배치하는 간단한 HTML 파일을 만들어 보겠습니다. express 앱이 이 정적 파일을 제공합니다.

mkdir public && cd public 
touch index.html
클라이언트 코드 복사

코드를 index.html에 복사

<!DOCTYPE html>

<body>
  <script type="module">
    const endpoint = "http://localhost:3000"

    // Gets an access token through which the client connects with your Web PubSub resource
    const webPubSubUrl = await getWebPubSubAccessToken(endpoint)

    // Opens a WebSocket connection with your Web PubSub resource using browser native WebSocket API 
    const socket = new WebSocket(webPubSubUrl)

    socket.addEventListener("open", () => {
      console.log("connection opened")
    })

    // Prints out the message when it arrives
    socket.addEventListener("message", (msg) => {
      console.log(msg)
    })

    async function getWebPubSubAccessToken(endpoint) {
      const response = await fetch(endpoint + "/negotiate")
      const { url } = await response.json()
      return url
    }
  </script>
</body>

</html>
클라이언트 프로그램 실행

원하는 웹 브라우저를 열고 서버가 수신 대기 중인 http://localhost:3000을 방문합니다.

브라우저 클라이언트가 Web PubSub 리소스 및 로컬로 실행되는 서버 앱과 직접 연결하는 것을 보여 주는 스크린샷.

publish.js가 실행 중인지 확인합니다. 페이지를 검사하고 네트워크 및 콘솔 패널을 열면 클라이언트가 Web PubSub 리소스에 성공적으로 연결되고 브로드캐스트된 메시지를 가져오는 것을 볼 수 있습니다.

Application Gateway를 통한 프록시 WebSocket 연결

Application Gateway는 WebSocket에 대한 기본 지원을 제공하므로 Application Gateway 리소스에 대한 구성을 변경할 필요가 없습니다. 클라이언트가 가리키는 엔드포인트를 변경하기만 하면 됩니다.

publish.js 파일을 찾아 두 가지를 변경합니다.

  • Application Gateway 리소스의 공용 IP를 보유할 변수를 선언합니다.
  • url 변수가 초기화되는 줄, let url=token.url을 변경합니다.
// ... code omitted from before
const appGatewayEndpoint = process.env.appGatewayEndpoint

app.get("/negotiate", async (req, res) => {
  const token = await webpubsub.getClientAccessToken()
  const url = "ws://" + appGatewayEndpoint + token.url.split(".com")[1]
  // ... code omitted from before
})
 
// ... code omitted from before

Application Gateway 리소스의 공용 IP를 찾고 환경 변수를 설정합니다.

export appGatewayEndpoint="<replace with the public IP of your Application Gateway resource>"

주의할 세 가지 사항.

  • Application Gateway는 http 트래픽만 수신하도록 구성되었으므로 wss:// 대신 ws://를 사용합니다.
  • 프로덕션에서는 Application Gateway 리소스에 대한 사용자 지정 도메인을 설정하고 HTTPs만 허용하도록 구성하는 것이 가장 좋습니다.
  • 액세스 토큰은 클라이언트가 Web PubSub 리소스와 연결할 수 있도록 자격 증명을 인코딩하므로 액세스 토큰을 있는 그대로 유지해야 합니다.

브라우저를 열고 http://localhost:3000을 다시 방문하면 WebSocket이 Application Gateway를 통해 성공적으로 프록시되고 Application Gateway에서 약 2초마다 메시지를 수신함을 확인할 수 있습니다.

브라우저 클라이언트가 Web PubSub 리소스 및 로컬로 실행되는 서버 앱과 간접적으로 연결하는 것을 보여 주는 스크린샷.

1단계 요약

1단계의 끝에 도달했습니다. 1단계를 따랐다면, 웹 클라이언트에서 직접, 그리고Application Gateway를 통해 간접적으로 Web PubSub 리소스에 액세스할 수 있음을 볼 수 있습니다. 또한 WebSocket에 대한 Application Gateway의 기본 지원이 작동하는 것을 보았습니다. 이것을 사용하도록 설정할 때 구성 변경은 필요하지 않습니다. 웹 클라이언트가 Application Gateway 엔드포인트를 가리키는지만 확인하면 됩니다. Web PubSub 서비스 SDK에서 생성된 액세스 URL의 나머지는 변경되지 않은 상태로 유지되어야 합니다.

2단계에서는 Web PubSub 리소스에 대한 공용 액세스를 닫아 보안을 강화합니다.

2단계: Web PubSub 리소스에 대한 공용 액세스 사용 안 함으로 설정

1단계의 결과는 공용 인터넷과 Application Gateway를 통해 Web PubSub 리소스에 액세스할 수 있다는 것입니다. Web PubSub 리소스는 동일한 Virtual Network에 없기 때문에 Application Gateway가 트래픽을 Web PubSub 리소스로 전달하면 공용 인터넷을 통해 Web PubSub의 공용 엔드포인트에 도달합니다. 이 상황은 바람직하지 않습니다.

Web PubSub 서비스는 액세스 제어 구성을 지원합니다. 이러한 구성 중 하나는 공용 인터넷에서 액세스를 사용하지 않도록 설정하는 것입니다. 완료되면 "저장"을 누릅니다.

Web PubSub의 공용 액세스를 사용하지 않도록 설정하는 방법을 보여 주는 스크린샷.

이제 동일한 명령을 실행하면 이전과 같이 "잘못된 허브 이름"이 표시되지 않고, 403 Forbidden이 표시됩니다.

curl https://<your-web-pubsub-resource-endpoint>/client

이제 Web PubSub 리소스에서 공용 액세스를 사용할 수 없습니다. 한 가지 영향은 1단계에서 설정된 Application Gateway도 연결할 수 없다는 것입니다. Application Gateway 엔드포인트에 대해 동일한 명령을 실행하면 504 Gateway Time-out이 표시됩니다.

curl http://<public-ip-of-your-application-gateway-resource>/client

Application Gateway와 동일한 Virtual Network에 Web PubSub 리소스를 가져와야 합니다. 프라이빗 엔드포인트를 만들어서 이를 수행합니다. 여기서 프라이빗 엔드포인트에 대해 자세히 알아볼 수 있습니다.

프라이빗 엔드포인트에 대한 별도의 서브넷 만들기

1단계에서는 Application Gateway가 있는 서브넷을 만들었습니다. Application Gateway에는 자체 서브넷이 필요하므로, 프라이빗 엔드포인트에 대한 다른 서브넷을 만들어야 합니다.

이전에 만든 Virtual Network 리소스를 찾아서 새 서브넷을 만듭니다.

다른 서브넷을 만드는 방법을 보여 주는 스크린샷.

Web PubSub 리소스의 프라이빗 엔드포인트 만들기

Azure Portal에서 Web PubSub 리소스를 찾아 "네트워킹" 블레이드로 이동합니다. 개별 서브넷을 만드는 방법을 보여 주는 스크린샷.

Web PubSub 리소스와 동일한 지역에 프라이빗 엔드포인트를 만듭니다. Web PubSub 리소스에 대한 프라이빗 엔드포인트를 만드는 방법을 보여 주는 스크린샷.

방금 만든 개별 서브넷을 선택합니다. 새로 만든 서브넷에 Web PubSub의 프라이빗 엔드포인트를 배치하는 방법을 보여 주는 스크린샷.

프라이빗 DNS 통합 사용 프라이빗 DNS 통합을 사용하도록 설정하는 방법을 보여 주는 스크린샷.

Application Gateway 리소스의 백 엔드 풀 새로 고침

Application Gateway 리소스는 Web PubSub 리소스에 대한 프라이빗 엔드포인트를 만들었다는 것을 알지 못합니다. Application Gateway 리소스를 찾고 백 엔드 풀을 새로 고칩니다. 백 엔드 풀을 새로 고치는 방법을 보여주는 스크린샷.

이제 이 명령을 다시 실행하면 "잘못된 허브 이름"이 다시 표시되고, 이것은 예상됩니다. Application Gateway는 공용 인터넷 대신 Virtual Network를 통해 프록시됨을 보여 줍니다.

curl http://<public-ip-of-your-application-gateway-resource>/client

게시 프로그램을 App Service 웹앱으로 배포

Web PubSub 리소스에 대한 공용 액세스가 사용할 수 없도록 설정되었으므로, 로컬 publish.js 프로그램이 리소스에 연결할 수 없습니다. Web PubSub 리소스가 있는 동일한 Virtual Network에 웹앱으로 프로그램을 배포해야 합니다.

웹앱을 ZIP 파일로 배포

소스 코드를 압축하고 Azure App Service에 배포하려면 클라이언트 코드를 약간 변경해야 합니다. /negotiate 엔드포인트는 더 이상 localhost에서 제공되지 않습니다.

공용 폴더에서 index.html을 찾아서 endpoint 변수가 선언된 줄을 변경합니다. 웹앱의 도메인 이름으로 바꿔야 합니다.

웹앱 리소스의 도메인 이름을 가져올 위치를 보여 주는 스크린샷.

  <script>
    // ...code omitted from before
   
   const endpoint = "<replace with your default domain name of your web app>"
    
    // ...code omitted from before
  </script>

웹앱은 앱을 ZIP 파일로 배포하는 편리한 명령을 제공합니다. az webapp up 명령과 이것이 자동화하는 작업에 대해 자세히 알아볼 수 있습니다.

1단계에서 만든 서버 폴더를 찾습니다.

## Makes sure you are in the right working directory
cd server 

## Make sure you have Azure CLI installed and log into your Azure account.
az login 

## Creates a ZIP file with the content in the server folder and deploys it as a Web App
az webapp up \
--sku B1 \
--name <the-name-of-your-web-app> \
--location <the-same-location-as-your-Web-PubSub-resource>

참고 항목

가이드를 따랐다면 지금까지 만든 리소스가 있는 Azure 구독으로 전환해야 할 수 있습니다. 구독을 전환하려면 이 설명서 문서에 설명된 명령을 따르세요.

환경 변수 설정

publish.js 프로그램이 시작되면 App Service는 환경 변수를 프로그램에서 사용할 수 있도록 합니다.

설정하고 publish.js에 사용할 수 있도록 하려면 두 가지 환경 변수가 필요합니다.

  • Azure Portal에서 Web PubSub 서비스에 대한 연결 문자열을 찾고 WebPubSubConnectionString 환경 변수를 설정합니다.
  • Application Gateway 리소스의 프런트 엔드 공용 IP를 찾고 appGatewayEndpoint 환경 변수를 설정합니다. 웹앱의 두 환경 변수를 설정하는 스크린샷.

웹앱에서 가상 네트워크 통합 사용

App Service를 사용하려면 Virtual Network에서 전용 서브넷이 필요합니다. Virtual Network 리소스로 이동하여 Web PubSub 리소스에 대해 했던 것과 같은 새 서브넷을 만듭니다.

새 서브넷이 만들어지면 웹앱 리소스의 "네트워킹" 블레이드로 이동하여 Virtual Network 통합을 사용하도록 설정합니다.

Virtual Network 통합을 사용하도록 설정하는 방법 - 1단계를 보여 주는 스크린샷.

Web PubSub 리소스가 있는 동일한 Virtual Network를 선택해야 합니다.  Virtual Network 통합을 사용하도록 설정하는 방법 - 2단계를 보여 주는 스크린샷.

자동 HTTP 리디렉션 끄기

기본적으로 웹앱은 HTTP 트래픽을 HTTPs로 리디렉션합니다. 이 기본 동작을 사용하지 않도록 설정해야 합니다. 이 작업은 프로덕션 워크로드에는 권장되지 않습니다. 자동 HTTPs 리디렉션을 끄는 방법을 보여 주는 스크린샷.

모든 것이 작동하는지 확인합니다.

지금까지 2단계에서는

  1. Web PubSub 리소스에 대한 공용 액세스를 사용 안 함으로 설정했습니다.
  2. 이에 대한 프라이빗 엔드포인트를 만들었습니다.
  3. Web PubSub 리소스에 연결할 수 있도록 Application Gateway 리소스의 백 엔드 풀을 새로 고쳤습니다.
  4. 클라이언트가 Web PubSub 리소스에 연결하기 위한 액세스 토큰을 가져오는 엔드포인트를 업데이트했습니다.
  5. publish.js를 웹앱으로 동일한 Virtual Network에 배포했습니다.
  6. 웹앱 리소스에 두 개의 환경 변수를 설정했습니다.
  7. HTTP 트래픽을 HTTPs로 리디렉션하는 웹앱의 기본 동작을 사용하지 않도록 설정했습니다.

이제 웹 브라우저를 열고 웹앱의 도메인 이름을 입력합니다. 페이지를 검사하고 네트워크 패널을 열면 클라이언트가 액세스 토큰을 위해 웹앱으로 이동한 다음, 토큰을 사용하여 Application Gateway와 WebSocket 연결을 설정하는 것을 볼 수 있습니다.

웹앱에서 액세스 토큰을 가져오는 방법을 보여 주는 스크린샷.

Application Gateway를 통해 WebSocket 연결을 성공적으로 설정했음을 보여 주는 스크린샷.

콘솔 패널이 열려 있는 경우 브로드캐스트된 메시지도 표시됩니다. Web PubSub에 대한 트래픽을 프록시하는 Application Gateway에서 메시지를 가져오는 과정을 보여 주는 스크린샷.