For security reasons, you must sign all API requests. Alibaba Cloud uses request signatures to verify the identities of API callers. Each API request must contain a signature, regardless of whether the API request is sent by using HTTP or HTTPS.
Signature algorithm
This topic describes the signature algorithm that is used in Function Compute. This signature algorithm is implemented in SDKs to sign API requests. This way, you do not need to manually calculate signatures. For more information, see Supported SDKs.
Function Compute checks whether a request is valid based on the Authorization
header field. If a function is configured with an HTTP trigger and allows anonymous
access, Function Compute does not check the validity of the request. A request can
pass the verification only when the client that sends the request uses the same signature
algorithm as Function Compute. If a request does not contain the Authorization header
field or the Authorization header field contains an invalid signature, Function Compute
returns the HTTP 403
error.
HTTP 403
error. For more information, see Billing.
signature = base64(hmac-sha256(HTTP_METHOD + "\n"
+ CONTENT-MD5 + "\n"
+ CONTENT-TYPE + "\n"
+ DATE + "\n"
+ CanonicalizedFCHeaders
+ CanonicalizedResource))
// The Authorization header field.
Authorization = "FC" + accessKeyID + ":" + signature
The following section describes the parameters:
HTTP_METHOD
: the HTTP method that is used to send a request. Specify the value in uppercase, for example, PUT, GET, POST, or DELETE.CONTENT-MD5
: the MD5 hash of the request content. If the request does not contain the Content-MD5 header field, leave this parameter empty.CONTENT-TYPE
: the type of the request content. Requests bound for Function Compute must be of theapplication/json
type.DATE
: required. The time when the signature is generated. The time must be in the GMT format.Notice The difference between the time when the signature is generated on the client and the time when Function Compute receives the request cannot exceed 15 minutes. Otherwise, Function Compute rejects the request.CanonicalizedFCHeaders
: the string that consists of all HTTP header fields whose names start withx-fc-
in the request. For more information about how to generate the string, see CanonicalizedFCHeaders.CanonicalizedResource
: the path in the request URL. In most cases, Function Compute decodes the path in a request URL and then removes the parameters in the path.- The path in a request URL is in the
$api-version/api-path
format, where:api-version
: the API version. The current API version is2016-08-15
.api-path
: the path that is used to call each API operation. For example, the path that is used to call the CreateService operation is/services
. For more information, see List of operations by function.
- Function Compute uses different methods to process
CanonicalizedResource
in common requests and CanonicalizedResource in the requests for functions that are configured with HTTP triggers and require authorization.- Request for a function that is configured with an HTTP trigger and requires authorization:
If parameters are specified in CanonicalizedResource in the request, Function Compute
separates the parameters with
\n
. The key-value pairs of the parameters are sorted in alphabetical order. If parameters are not specified in CanonicalizedResource in the request, Function Compute appends\n
to the end of the value of CanonicalizedResource. Example:// The path in the URL of a request for a function that is configured with an HTTP trigger and requires authorization. /2016-08-15/proxy/service-name/func-name/path-with-%20-space/action? x=1&a=2&x=3&with%20space=foo%20bar // The URL-decoded path. /2016-08-15/proxy/service-name/func-name/path-with- -space/action? x=1&a=2&x=3&with space=foo bar // CanonicalizedResource in a request for a function that is configured with an HTTP trigger and requires authorization. /2016-08-15/proxy/service-name/func-name/path-with- -space/action\na=2\nwith space=foo bar\nx=1\nx=3 // The path in the URL of a common request. /2016-08-15/service-name/func-name/path-with-%20-space/action? x=1&a=2&x=3&with%20space=foo%20bar // The URL-decoded path. /2016-08-15/service-name/func-name/path-with- -space/action? x=1&a=2&x=3&with space=foo bar // CanonicalizedResource in a common request. /2016-08-15/service-name/func-name/path-with- -space/action
Note If a key in CanonicalizedResource maps to multiple values, Function Compute considers the key and values as a whole when it sorts the key-value pairs. - Common request: Function Compute performs URL decoding on the value of
CanonicalizedResource
in the request and obtains the string to the left of the question mark (?
). The parameters to the right of the question mark (?
) are discarded.Note Common requests include all requests except the requests for functions that are configured with HTTP triggers and require authorization.
- Request for a function that is configured with an HTTP trigger and requires authorization:
If parameters are specified in CanonicalizedResource in the request, Function Compute
separates the parameters with
- The path in a request URL is in the
hmac-sha 256
: the key that is used to generate the signature. Your AccessKey secret must be used as the key.You can use the following pseudocode to verify the signature scheme:
// Create a string. function composeStringToSign(method, path, headers, queries) { var contentMD5 = headers['content-md5'] || ''; var contentType = headers['content-type'] || ''; var date = headers['date']; var signHeaders = buildCanonicalHeaders(headers, 'x-fc-'); var u = url.parse(path); var pathUnescaped = decodeURIComponent(u.pathname); var str = `${method}\n${contentMD5}\n${contentType}\n${date}\n${signHeaders}${pathUnescaped}`; if (queries) { var params = []; Object.keys(queries).forEach(function (key) { var values = queries[key]; var type = typeof values; if (type === 'string') { params.push(`${key}=${values}`); return; } if (type === 'object' && values instanceof Array) { queries[key].forEach(function (value) { params.push(`${key}=${value}`); }); } }); params.sort(); str += '\n' + params.join('\n'); } return str; } // Use HMAC-SHA256 and Base64 to calculate the signature. The value of the source parameter is the string that is created by using the preceding code. function signString(source, secret) { const buff = crypto.createHmac('sha256', secret) .update(source, 'utf8') .digest(); return new Buffer(buff, 'binary').toString('base64'); }
CanonicalizedFCHeaders
To generate a value for CanonicalizedFCHeaders, perform the following steps: