Task Management
signature = base64(HMAC-SHA256(secret_key, signingString))
Where:
- secret_key: the token used when creating the task
- signingString: the string to be signed, constructed as follows
signingString = http_method + "\n" + http_uri + "\n" + canonical_query_string + "\n" + access_key + "\n" + Date + "\n" + signed_headers_string
Parameter descriptions:
-
http_method: HTTP request method such as GET, PUT, POST, etc., must be in all uppercase
-
http_uri: the path part of the URL, extracted using a standard URL parser from the callback_url, must start with "/", and an empty path should be "/"
-
canonical_query_string: the query string part of the URL, extracted using a standard URL parser from the callback_url, if there are no query parameters, use an empty string
-
access_key: API identifier, fixed as "vidu"
-
Date: the Date in the request header (in GMT format)
-
signed_headers_string: extract headers specified in X-HMAC-SIGNED-HEADERS from the request in order, and concatenate them in the following format:
HeaderKey1 + ":" + HeaderValue1 + "\n" + HeaderKey2 + ":" + HeaderValue2 + "\n" + ... HeaderKeyN + ":" + HeaderValueN + "\n"
Headers related to the signature include:
- Date: time in GMT format, e.g., "Tue, 06 May 2025 12:09:42 GMT"
- x-request-nonce: random string to prevent replay attacks
- X-HMAC-SIGNED-HEADERS: list of header fields used in the signature, separated by semicolons, e.g., "Date;x-request-nonce"
- X-HMAC-SIGNATURE: the final computed signature
- X-HMAC-ALGORITHM: signature algorithm, fixed as "hmac-sha256"
- X-HMAC-ACCESS-KEY: access key identifier, fixed as "vidu"
Using a standard URL parser to parse the full URL
http://127.0.0.1:8080/vidu/callback?name=james&age=36POST /vidu/callback name=james&age=36 vidu Tue, 06 May 2025 12:09:42 GMT Date:Tue, 06 May 2025 12:09:42 GMT x-request-nonce:123e4567-e89b-12d3-a456-426614174000
Notes:
- The string ends with a newline character
- /vidu/callback is the Path part extracted from the URL using a standard URL parser
- name=james&age=36 is the RawQuery part extracted from the URL using a standard URL parser
- The secret used for the signature is the application's TokenSecret
import base64 import hmac import hashlib import urllib.parse import uuid def generate_signature(secret_key, http_method, callback_url, date, headers, header_order): # Parse the URL using a standard URL parsing library parsed_url = urllib.parse.urlparse(callback_url) uri = parsed_url.path or "/" query_string = parsed_url.query or "" # Construct the signing string signing_string = ( f"{http_method}\n" f"{uri}\n" f"{query_string}\n" f"vidu\n" # Fixed access_key f"{date}\n" ) # Add header information for header in header_order: signing_string += f"{header}:{headers[header]}\n" # Compute the signature h = hmac.new( secret_key.encode('utf-8'), signing_string.encode('utf-8'), hashlib.sha256 ) # Base64 encode return base64.b64encode(h.digest()).decode('utf-8') # Example usage secret_key = 'your_secret_token' http_method = 'POST' callback_url = 'http://127.0.0.1:8080/vidu/callback?name=james&age=36' date = 'Tue, 06 May 2025 12:09:42 GMT' nonce = str(uuid.uuid4()) headers = { 'Date': date, 'x-request-nonce': nonce } header_order = ['Date', 'x-request-nonce'] signature = generate_signature(secret_key, http_method, callback_url, date, headers, header_order) print(signature) # Build the complete HTTP request headers request_headers = { 'Date': date, 'x-request-nonce': nonce, 'X-HMAC-SIGNED-HEADERS': ';'.join(header_order), 'X-HMAC-SIGNATURE': signature, 'X-HMAC-ALGORITHM': 'hmac-sha256', 'X-HMAC-ACCESS-KEY': 'vidu', 'Content-Type': 'application/json' }
package main import ( "crypto/hmac" "crypto/sha256" "encoding/base64" "fmt" "net/url" "strings" "time" "github.com/google/uuid" ) func generateSignature(secretKey, httpMethod, callbackURL, date string, headers map[string]string, headerOrder []string) (string, error) { // Parse the URL using a standard URL parsing library uri := "/" queryString := "" parsedURL, err := url.Parse(callbackURL) if err != nil { return "", err } // Get the Path part if parsedURL.Path != "" { uri = parsedURL.Path } // Get the query parameters part queryString = parsedURL.RawQuery var signingStringBuilder strings.Builder // Add HTTP method signingStringBuilder.WriteString(httpMethod) signingStringBuilder.WriteString("\n") // Add URI signingStringBuilder.WriteString(uri) signingStringBuilder.WriteString("\n") // Add query string signingStringBuilder.WriteString(queryString) signingStringBuilder.WriteString("\n") // Add access key signingStringBuilder.WriteString("vidu") signingStringBuilder.WriteString("\n") // Add date signingStringBuilder.WriteString(date) signingStringBuilder.WriteString("\n") // Add headers for _, header := range headerOrder { signingStringBuilder.WriteString(header) signingStringBuilder.WriteString(":") signingStringBuilder.WriteString(headers[header]) signingStringBuilder.WriteString("\n") } signingString := signingStringBuilder.String() // Generate HMAC-SHA256 h := hmac.New(sha256.New, []byte(secretKey)) h.Write([]byte(signingString)) // Base64 encode return base64.StdEncoding.EncodeToString(h.Sum(nil)), nil } func main() { secretKey := "your_secret_token" httpMethod := "POST" callbackURL := "http://127.0.0.1:8080/vidu/callback?name=james&age=36" currentTime := time.Now().UTC() date := currentTime.Format("Mon, 02 Jan 2006 15:04:05 GMT") nonce := uuid.New().String() headers := map[string]string{ "Date": date, "x-request-nonce": nonce, } headerOrder := []string{"Date", "x-request-nonce"} signature, err := generateSignature(secretKey, httpMethod, callbackURL, date, headers, headerOrder) if err != nil { fmt.Printf("Error generating signature: %v\n", err) return } fmt.Println("Signature:", signature) // Build the complete HTTP request headers requestHeaders := map[string]string{ "Date": date, "x-request-nonce": nonce, "X-HMAC-SIGNED-HEADERS": strings.Join(headerOrder, ";"), "X-HMAC-SIGNATURE": signature, "X-HMAC-ALGORITHM": "hmac-sha256", "X-HMAC-ACCESS-KEY": "vidu", "Content-Type": "application/json", } for k, v := range requestHeaders { fmt.Printf("%s: %s\n", k, v) } }
- The signing string is very sensitive to formatting, including newline characters and spaces
- When using multi-line strings, make sure:
- There are no extra indentation spaces
- The format between lines is precise
- The string ends with a newline character
- The headers specified in X-HMAC-SIGNED-HEADERS must be concatenated in the specified order
- The HTTP method must be uppercase (e.g., POST, GET, etc.)
- The URI must start with "/"
- Query parameters must be in raw format, without including the "?"
- During signature generation, the system uses a standard URL parser to extract the URI and query parameter parts from callback_url
- To prevent replay attacks, use the x-request-nonce header with a random value (UUID format)