共用方式為


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

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

注意

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

必要條件

有問題嗎? 讓我們知道。

在 Azure 上建立必要資源

建立 Azure SignalR Service 資源

您的應用程式將存取 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 函數專案:

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

依預設,產生的專案包含 host.json 檔案,其中含有具備 SignalR 延伸模組的延伸模組套件組合。 如需延伸模組套件組合的詳細資料,請參閱註冊 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>"
  }
}

在上述程式碼中:

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

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

  • AzureWebJobsStorage 設定中輸入儲存體帳戶連接字串。

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

有問題嗎? 讓我們知道。

建立向 Azure SignalR Service 驗證使用者的函數

當聊天應用程式首先在瀏覽器中開啟時,它需要有效的連線認證以連線至 Azure SignalR 服務。 在函數應用程式中建立名為 negotiate 的 HTTP 觸發程序函數以傳回此連線資訊。

注意

由於 SignalR 用戶端需要結尾為 /negotiate 的端點,因此此函數的名稱必須為 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 Service 中樞。

    此函式會取得輸入繫結中的 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 Service 的用戶端。 這會在每個用戶端上叫用名為 newMessage 的函數。

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

  3. 儲存檔案。

有問題嗎? 讓我們知道。

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

聊天應用程式 UI 是簡易單頁應用程式 (SPA),透過使用 ASP.NET Core SignalR JavaScript 用戶端以 Vue JavaScript 架構所建立。 為了簡單起見,函數應用程式會裝載網頁。 在實際執行環境中,您可以使用 Static 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、X、Microsoft 帳戶和 Google 進行驗證。 您將使用 Microsoft 作為本教學課程的識別提供者。

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

  2. 依序選取 [設定]>[驗證]

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

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

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

    用於新增識別提供者的頁面螢幕擷取畫面。

完成的設定會建立應用程式註冊以將識別提供者與函數應用程式建立關聯。

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

嘗試使用應用程式

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

已驗證線上用戶端聊天應用程式的螢幕擷取畫面。

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

有問題嗎? 讓我們知道。

清除資源

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

警告

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

有問題嗎? 讓我們知道。

下一步

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

有問題嗎? 讓我們知道。