

# 使用 WebSocket 庫生成預先簽署的請求
<a name="network-analyzer-generate-request"></a>

下文顯示如何生成預先簽署的請求，以便您可以使用 WebSocket 庫將請求傳送到服務。

## 將 WebSocket 請求的政策新增到 IAM 角色
<a name="network-analyzer-iam"></a>

若要使用 WebSocket 通訊協定呼叫網路分析器，您需要將以下政策附加至提出此請求的 AWS Identity and Access Management (IAM) 角色。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "iotwireless:StartNetworkAnalyzerStream",
            "Resource": "*"
        }
    ]
}
```

## 建立預先簽署的 URL
<a name="network-analyzer-presigned-url"></a>

為您的 WebSocket 請求建構 URL，其中包含在您的應用程式和網路分析器之間建立通訊時所需的資訊。若要驗證請求的身分，WebSocket 串流使用 Amazon Signature 第 4 版程序來簽署請求。如需有關 Signature 第 4 版的詳細資訊，請參閱《Amazon Web Services 一般參考》**中的[簽署 AWS API 請求](https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html)。

若要呼叫網路分析器，請使用 `StartNetworkAnalyzerStream` 請求 URL。將使用先前提及的 IAM 角色的憑證簽署請求。URL 採用下列格式，並會新增分行符以增加可讀性。

```
GET wss://api.iotwireless.<region>.amazonaws.com/start-network-analyzer-stream?X-Amz-Algorithm=AWS4-HMAC-SHA256
   &X-Amz-Credential=Signature Version 4 credential scope
   &X-Amz-Date=date
   &X-Amz-Expires=time in seconds until expiration
   &X-Amz-Security-Token=security-token
   &X-Amz-Signature=Signature Version 4 signature 
   &X-Amz-SignedHeaders=host
```

使用以下值作為 Singature 第 4 版的參數：
+ **X-Amz-Algorithm**：您在簽署程序中使用的演算法。唯一有效的值為 `AWS4-HMAC-SHA256`。
+ **X-Amz-Credential**：透過串連存取金鑰 ID 和憑證範圍元件所形成的以斜線 (「/」) 分隔的字串。憑證範圍包括 YYYYMMDD 格式的日期、AWS 區域、服務名稱和特殊終止字串 (aws4\$1request)。
+ **X-Amz-Date**：簽章的建立日期與時間。依照《Amazon Web Services 一般參考**》中 [Signature 第 4 版中的處理日期](https://docs.aws.amazon.com/general/latest/gr/sigv4-date-handling.html)指示生成日期與時間。
+ **X-Amz-Expires**：憑證在逾期前尚有多少時間 (以秒為單位)。最大值為 300 秒 (5 分鐘)。
+ **X-Amz-Security-Token**：(選用) 用於臨時安全憑證的 Signature 第 4 版字符。如果您指定此參數，請將其包含在正式請求中。如需詳細資訊，請參閱《AWS Identity and Access Management 使用者指南**》中的[請求臨時安全憑證](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html)。
+ **X-Amz-Signature**：您為請求所生成的 Signature 第 4 版簽章。
+ **X-Amz-SignedHeaders**：在為請求建立簽章時，所簽署的標頭。唯一有效的值為 `host`。

## 建構請求 URL 以及建立 Signature 第 4 版簽章
<a name="connect-iot-network-analyzer-construct-url-sign"></a>

若要為請求建構 URL 及建立 Signature 第 4 版簽章，請使用下列步驟。這些範例是虛擬程式碼。

### 任務 1：建立正式請求
<a name="canonical-request"></a>

建立字串，其中包括來自您的請求的資訊 (使用標準化格式)。這可確保當 AWS 收到請求時，可以計算出您在 [任務 3：計算簽章](#calculate-signature) 中計算出的相同簽章。如需詳細資訊，請參閱《[Amazon Web Services 一般參考](https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html)》中的*為 Signature 第 4 版建立正式請求*。

1. 在應用程式中定義請求的變數。

   ```
   # HTTP verb
   method = "GET"
   # Service name
   service = "iotwireless"
   # AWS 區域
   region = "AWS 區域"
   # Service streaming endpoint
   endpoint = "wss://api.iotwireless.region.amazonaws.com"
   # Host
   host = "api.iotwireless.<region>.amazonaws.com"
   # Date and time of request
   amz-date = YYYYMMDD'T'HHMMSS'Z'
   # Date without time for credential scope
   datestamp = YYYYMMDD
   ```

1. 建立正式的 URI (統一資源識別符)。正式 URI 是介於網域與查詢字串之間的部分 URI。

   ```
   canonical_uri = "/start-network-analyzer-stream"
   ```

1. 建立正式標頭和已簽章標頭。請注意正式標頭中的結尾 `\n`。
   + 附加小寫標頭名稱，後面接著冒號。
   + 為該標頭附加逗號分隔的值清單。不要在有多個值的標頭中排序值。
   + 附加新的一行 (`\n`)。

   ```
   canonical_headers = "host:" + host + "\n"
   signed_headers = "host"
   ```

1. 演算法必須符合雜湊演算法。您必須使用 SHA-256。

   ```
   algorithm = "AWS4-HMAC-SHA256"
   ```

1. 建立憑證的範圍，將衍生的金鑰範圍限定於提出請求的日期、區域和服務。

   ```
   credential_scope = datestamp + "/" + region + "/" + service + "/" + "aws4_request"
   ```

1. 建立正式查詢字串。查詢字串值必須是 URL 編碼並以名稱排序。
   + 依照字元字碼指標的參數名稱遞增排序。​具有重複名稱的參數應依數值排序。例如，以大寫字母 F 開頭的參數名稱，放在以小寫字母 b 開頭的參數名稱之前。
   + URI 編碼不能執行 [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) 所定義的任何未預留字元：A–Z、a–z、0–9、連字號 (-)、底線 (\$1)、句點 ( . ) 和波狀符號 ( \$1 )。
   + 對所有其他含有 %XY 的字元執行百分比編碼，其中 X 和 Y 是十六進位字元 (0-9 和大寫 A-F)。例如，空間字元必須編碼為 %20 (而非像有些編碼結構描述那樣使用「\$1」)，而延伸的 UTF-8 字元必須採用 %XY%ZA%BC 格式。
   + 對參數值中的任何等於 (=) 字元進行雙倍編碼。

   ```
   canonical_querystring  = "X-Amz-Algorithm=" + algorithm
   canonical_querystring += "&X-Amz-Credential="+ URI-encode(access key + "/" + credential_scope)
   canonical_querystring += "&X-Amz-Date=" + amz_date 
   canonical_querystring += "&X-Amz-Expires=300"
   canonical_querystring += "&X-Amz-Security-Token=" + token
   canonical_querystring += "&X-Amz-SignedHeaders=" + signed_headers
   canonical_querystring += "&language-code=en-US&media-encoding=pcm&sample-rate=16000"
   ```

1. 建立承載的雜湊。對於 GET 請求，承載為空字串。

   ```
   payload_hash = HashSHA256(("").Encode("utf-8")).HexDigest()
   ```

1. 結合所有元素來建立正式請求。

   ```
   canonical_request = method + '\n' 
      + canonical_uri + '\n' 
      + canonical_querystring + '\n' 
      + canonical_headers + '\n' 
      + signed_headers + '\n' 
      + payload_hash
   ```

### 任務 2：建立要簽署的字串
<a name="create-urlsign"></a>

要簽署的字串包含有關您的請求的中繼資料。您在下一個步驟計算請求簽章時，使用此字串登入。如需詳細資訊，請參閱《[Amazon Web Services 一般參考](https://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html)》中的*建立 Signature 第 4 版的登入字串*。

```
string_to_sign=algorithm + "\n"
   + amz_date + "\n"
   + credential_scope + "\n"
   + HashSHA256(canonical_request.Encode("utf-8")).HexDigest()
```

### 任務 3：計算簽章
<a name="calculate-signature"></a>

從您的 AWS 私密存取金鑰衍生簽署金鑰。為了提供更大程度的保護，衍生的金鑰有專屬的日期、服務和 AWS 區域。您使用衍生的金鑰來簽署請求。如需詳細資訊，請參閱《[Amazon Web Services 一般參考](https://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html)》中的*為 AWS Signature 第 4 版計算簽章*。

此程式碼假設您已實作 `GetSignatureKey` 函數來衍生簽署金鑰。如需詳細資訊和範例函數，請參閱《[Amazon Web Services 一般參考](https://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html)》中的*如何衍生 Signature 第 4 版的簽署密鑰範例*。

函數 `HMAC(key, data)` 代表 HMAC-SHA256 函數，它會以二進位格式傳回結果。

```
#Create the signing key
signing_key = GetSignatureKey(secret_key, datestamp, region, service)
                
# Sign the string_to_sign using the signing key
signature = HMAC.new(signing_key, (string_to_sign).Encode("utf-8"), Sha256()).HexDigest
```

### 任務 4：將簽署資訊添加至請求並建立請求 URL
<a name="sign-request"></a>

您計算簽章之後，請將簽章新增到查詢字串。如需詳細資訊，請參閱《[Amazon Web Services 一般參考](https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html)》中的*新增簽章至請求*。

```
#Add the authentication information to the query string
canonical_querystring += "&X-Amz-Signature=" + signature
                
# Sign the string_to_sign using the signing key
request_url = endpoint + canonical_uri + "?" + canonical_querystring
```

## 後續步驟
<a name="network-analyzer-request-next"></a>

您現在可以使用請求 URL 與您的 WebSocket 程式庫，以便向服務提出請求並觀察訊息。如需詳細資訊，請參閱[WebSocket 訊息和狀態碼](network-analyer-messages-status.md)。