教學課程:使用 Azure Functions 進行 Azure SignalR 服務驗證

在本逐步教學課程中,您會使用下列技術來建置具有驗證和私人訊息的聊天室:

  • Azure Functions:用來驗證使用者及傳送聊天訊息的後端 API。
  • Azure SignalR Service:將新訊息廣播至已連線聊天客戶端的服務。
  • Azure 儲存體:Azure Functions 所需的 儲存體 服務。
  • Azure App 服務:提供使用者驗證的服務。

注意

您可以從 GitHub 取得本文所述的程式代碼。

必要條件

有問題嗎? 請告訴我們。

在 Azure 上建立基本資源

建立 Azure SignalR 服務資源

您的應用程式將會存取 Azure SignalR Service 實例。 使用下列步驟,使用 Azure 入口網站 建立 Azure SignalR Service 實例:

  1. Azure 入口網站 中,選取 [建立資源]+ 按鈕。

  2. 搜尋 SignalR 服務 並加以選取。

  3. 選取 建立

  4. 輸入下列資訊。

    名稱
    資源群組 建立具有唯一名稱的新資源群組。
    資源名稱 輸入 Azure SignalR Service 實例的唯一名稱。
    區域 選取接近您的區域。
    定價層 選取 [免費]
    服務模式 選取 [無伺服器]
  5. 選取 [檢閱 + 建立] 。

  6. 選取 建立

有問題嗎? 請告訴我們。

建立 Azure 函式應用程式和 Azure 記憶體帳戶

  1. 從 Azure 入口網站 的首頁,選取 [建立資源]。+

  2. 搜尋函 式應用程式 並加以選取。

  3. 選取 建立

  4. 輸入下列資訊。

    名稱
    資源群組 搭配您的 Azure SignalR Service 實例使用相同的資源群組。
    函數應用程式名稱 輸入函式應用程式的唯一名稱。
    執行階段堆疊 選取 [Node.js]
    區域 選取接近您的區域。
  5. 根據預設,新的 Azure 記憶體帳戶會與函式應用程式一起建立在相同的資源群組中。 如果您想要在函式應用程式中使用另一個記憶體帳戶,請切換至 [ 裝載 ] 索引標籤以選擇帳戶。

  6. 選取 [檢閱 + 建立],然後選取 [建立]。

在本機建立 Azure Functions 專案

初始化函式應用程式

  1. 從命令行建立專案的根資料夾,並變更為資料夾。

  2. 在您的終端機中執行下列命令,以建立新的 JavaScript Functions 專案:

func init --worker-runtime node --language javascript --name my-app --model V4

根據預設,產生的專案會包含包含 SignalR 延伸模組套件組合的 host.json檔案。 如需延伸模組套件組合的詳細資訊,請參閱 註冊 Azure Functions 系結延伸模組

設定應用程式設定

當您在本機執行和偵錯 Azure Functions 運行時間時,函式應用程式會從 local.settings.json讀取應用程式設定。 使用 Azure SignalR Service 實例的 連接字串 和您稍早建立的記憶體帳戶來更新此檔案。

使用下列程式代碼取代local.settings.json的內容

{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "node",
    "AzureWebJobsStorage": "<your-storage-account-connection-string>",
    "AzureSignalRConnectionString": "<your-Azure-SignalR-connection-string>"
  }
}

在上述程式碼中:

  • 在設定中輸入 Azure SignalR Service 連接字串AzureSignalRConnectionString

    若要取得字串,請移至 Azure 入口網站 中的 Azure SignalR Service 實例。 在 [設定] 區段中,找出 [金鑰] 設定。 選取 連接字串 右邊的 [複製] 按鈕,將它複製到剪貼簿。 您可以使用主要或次要 連接字串。

  • 在設定中輸入記憶體帳戶 連接字串AzureWebJobsStorage

    若要取得字串,請移至 Azure 入口網站 中的記憶體帳戶。 在 [安全性 + 網路] 區段,找出 [存取金鑰] 設定。 選取 連接字串 右邊的 [複製] 按鈕,將它複製到剪貼簿。 您可以使用主要或次要 連接字串。

有問題嗎? 請告訴我們。

建立函式以向 Azure SignalR Service 驗證使用者

聊天應用程式第一次在瀏覽器中開啟時,需要有效的連線認證才能連線到 Azure SignalR Service。 在函式應用程式中建立名為 的 negotiate HTTP 觸發程式函式,以傳回此聯機資訊。

注意

此函式必須命名 negotiate ,因為 SignalR 用戶端需要以 結尾的 /negotiate端點。

  1. 從根項目資料夾,使用下列命令,從內建範本建立 negotiate 函式:

    func new --template "HTTP trigger" --name negotiate
    
  2. 開啟 src/functions/negotiate.js,更新內容,如下所示:

    const { app, input } = require('@azure/functions');
    
    const inputSignalR = input.generic({
        type: 'signalRConnectionInfo',
        name: 'connectionInfo',
        hubName: 'default',
        connectionStringSetting: 'AzureSignalRConnectionString',
    });
    
    app.post('negotiate', {
        authLevel: 'anonymous',
        handler: (request, context) => {
            return { body: JSON.stringify(context.extraInputs.get(inputSignalR)) }
        },
        route: 'negotiate',
        extraInputs: [inputSignalR],
    });
    

    函式包含 HTTP 觸發程式系結,以接收來自 SignalR 用戶端的要求。 函式也包含 SignalR 輸入系結,以產生有效的認證,讓用戶端連線到名為 default的 Azure SignalR 服務中樞。

    此函式會從輸入系結取得 SignalR 連線資訊,並將它傳回 HTTP 回應本文中的用戶端。

    系結中signalRConnectionInfo沒有userId本機開發的屬性。 您稍後會新增它,以在將函式應用程式部署至 Azure 時設定 SignalR 連線的用戶名稱。

有問題嗎? 請告訴我們。

建立函式以傳送聊天訊息

Web 應用程式也需要 HTTP API 來傳送聊天訊息。 建立 HTTP 觸發程式函式,將訊息傳送至使用 Azure SignalR Service 的所有已連線用戶端:

  1. 從根項目資料夾,使用下列命令,從範本建立名為 sendMessage 的 HTTP 觸發程式函式:

    func new --name sendMessage --template "Http trigger"
    
  2. 開啟 src/functions/sendMessage.js 檔案,更新內容,如下所示:

    const { app, output } = require('@azure/functions');
    
    const signalR = output.generic({
        type: 'signalR',
        name: 'signalR',
        hubName: 'default',
        connectionStringSetting: 'AzureSignalRConnectionString',
    });
    
    app.http('messages', {
        methods: ['POST'],
        authLevel: 'anonymous',
        extraOutputs: [signalR],
        handler: async (request, context) => {
            const message = await request.json();
            message.sender = request.headers && request.headers.get('x-ms-client-principal-name') || '';
    
            let recipientUserId = '';
            if (message.recipient) {
                recipientUserId = message.recipient;
                message.isPrivate = true;
            }
            context.extraOutputs.set(signalR,
                {
                    'userId': recipientUserId,
                    'target': 'newMessage',
                    'arguments': [message]
                });
        }
    });
    

    函式包含 HTTP 觸發程式和 SignalR 輸出系結。 它會從 HTTP 要求擷取本文,並將其傳送至連線至 Azure SignalR 服務的用戶端。 它會在每個用戶端上叫用名為 newMessage 的函式。

    函式可以讀取發件者的身分識別,並可接受 recipient 訊息本文中的值,讓您私下將訊息傳送給單一使用者。 您稍後將在教學課程中使用這些功能。

  3. 儲存檔案。

有問題嗎? 請告訴我們。

裝載聊天用戶端的 Web 使用者介面

聊天應用程式的UI是使用 ASP.NET Core SignalR JavaScript用戶端,以 Vue JavaScript 架構建立的簡單單頁應用程式(SPA)。 為了簡單起見,函式應用程式會裝載網頁。 在生產環境中,您可以使用 靜態 Web Apps 來裝載網頁。

  1. 在函式專案的根目錄中,建立名為 index.html 的檔案。

  2. 將index.html的內容複製並貼到您的檔案。 儲存檔案。

  3. 從根項目資料夾,使用此命令從範本建立名為 index 的 HTTP 觸發程式函式:

    func new --name index --template "Http trigger"
    
  4. 將 src/functions/index.js的內容修改為下列程式代碼:

    const { app } = require('@azure/functions');
    const { readFile } = require('fs/promises');
    
    app.http('index', {
        methods: ['GET'],
        authLevel: 'anonymous',
        handler: async (context) => {
            const content = await readFile('index.html', 'utf8', (err, data) => {
                if (err) {
                    context.err(err)
                    return
                }
            });
    
            return {
                status: 200,
                headers: {
                    'Content-Type': 'text/html'
                },
                body: content,
            };
        }
    });
    

    函式會讀取靜態網頁,並將它傳回給使用者。

  5. 在本機測試您的應用程式。 使用這個指令啟動函式應用程式:

    func start
    
  6. 在網頁瀏覽器中開啟 http://localhost:7071/api/index 。 聊天網頁應該會出現。

    本機聊天用戶端 Web 使用者介面的螢幕快照。

  7. 在聊天方塊中輸入訊息。

    選取 Enter 鍵之後,訊息會出現在網頁上。 因為未設定 SignalR 用戶端的用戶名稱,因此您會以匿名方式傳送所有訊息。

有問題嗎? 請告訴我們。

部署至 Azure 並啟用驗證

您已在本機執行函式應用程式和聊天應用程式。 現在,將它們部署至 Azure,並啟用驗證和私人傳訊。

設定函式應用程式以進行驗證

到目前為止,聊天應用程式會匿名運作。 在 Azure 中,您將使用 App Service 驗證 來驗證使用者。 已驗證使用者的使用者識別碼或使用者名稱會傳遞至系結, SignalRConnectionInfo 以產生以使用者身分驗證的連接資訊。

  1. 開啟 src/functions/negotiate.js 檔案。

  2. 使用 userId{headers.x-ms-client-principal-name}將 屬性插入系結中inputSignalR。 這個值是系 結運算式 ,會將 SignalR 用戶端的使用者名稱設定為已驗證用戶的名稱。 系結現在看起來應該像下列範例:

    const inputSignalR = input.generic({
        type: 'signalRConnectionInfo',
        name: 'connectionInfo',
        hubName: 'default',
        connectionStringSetting: 'AzureSignalRConnectionString',
        userId: '{headers.x-ms-client-principal-name}'
    });
    
  3. 儲存檔案。

將函式應用程式部署至 Azure

使用下列命令將函式應用程式部署至 Azure:

func azure functionapp publish <your-function-app-name> --publish-local-settings

此選項 --publish-local-settings 會將本機設定從 local.settings.json 檔案發佈至 Azure,因此您不需要再次在 Azure 中設定它們。

啟用 App Service 驗證

Azure Functions 支援使用 Microsoft Entra ID、Facebook、Twitter、Microsoft 帳戶和 Google 進行驗證。 您將使用 Microsoft 作為本教學課程的識別提供者。

  1. 在 Azure 入口網站 中,移至函式應用程式的資源頁面。

  2. 選取 [設定> Authentication]。

  3. 選取 [新增識別提供者]

    函式應用程式驗證頁面的螢幕快照,以及用於新增識別提供者的按鈕。

  4. 在 [ 識別提供者 ] 列表中,選取 [Microsoft]。 然後選取 [新增]。

    用於新增識別提供者的頁面螢幕快照。

完成的設定會建立應用程式註冊,讓識別提供者與函式應用程式產生關聯。

如需所支持識別提供者的詳細資訊,請參閱下列文章:

試用應用程式

  1. 開啟 [https://<YOUR-FUNCTION-APP-NAME>.azurewebsites.net/api/index]。
  2. 選取 [登入 ] 以向您選擇的驗證提供者進行驗證。
  3. 在主要聊天方塊中輸入公用訊息,以傳送公用訊息。
  4. 選取聊天記錄中的用戶名稱,以傳送私人訊息。 只有選取的收件者會收到這些訊息。

已驗證的在線用戶端聊天應用程式的螢幕快照。

恭喜! 您已部署即時無伺服器聊天應用程式。

有問題嗎? 請告訴我們。

清除資源

若要清除您在本教學課程中建立的資源,請使用 Azure 入口網站 刪除資源群組。

警告

刪除資源群組會刪除它包含的所有資源。 如果資源群組包含本教學課程範圍以外的資源,也會刪除它們。

有問題嗎? 請告訴我們。

下一步

在本教學課程中,您已瞭解如何搭配 Azure SignalR Service 使用 Azure Functions。 深入瞭解如何使用適用於 Azure Functions 的 Azure SignalR Service 系結建置即時無伺服器應用程式:

有問題嗎? 讓我們知道。