Last active
August 9, 2022 00:01
-
-
Save anjesh/3d5ec6bfde0b12a8e91f435a9e07ea97 to your computer and use it in GitHub Desktop.
Mturk working code for `GetAccountBalance` with signature generation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
# adapted from http://usefulangle.com/post/34/aws-s3-upload-api-php-curl and works with Mturk | |
$headerBlacklist = [ | |
'cache-control' => true, | |
'content-type' => true, | |
'content-length' => true, | |
'expect' => true, | |
'max-forwards' => true, | |
'pragma' => true, | |
'range' => true, | |
'te' => true, | |
'if-match' => true, | |
'if-none-match' => true, | |
'if-modified-since' => true, | |
'if-unmodified-since' => true, | |
'if-range' => true, | |
'accept' => true, | |
'authorization' => true, | |
'proxy-authorization' => true, | |
'from' => true, | |
'referer' => true, | |
'user-agent' => true, | |
'x-amzn-trace-id' => true, | |
'aws-sdk-invocation-id' => true, | |
'aws-sdk-retry' => true, | |
]; | |
/// AWS API keys | |
$aws_access_key_id = 'xx'; | |
$aws_secret_access_key = 'xxxx'; | |
// AWS region and Host Name (Host names are different for each AWS region) | |
// As an example these are set to us-east-1 (US Standard) | |
$host_name = 'mturk-requester-sandbox.us-east-1.amazonaws.com'; | |
$aws_region = 'us-east-1'; | |
$aws_service_name = 'mturk-requester'; | |
// UTC timestamp and date | |
$timestamp = gmdate('Ymd\THis\Z'); | |
$date = gmdate('Ymd'); | |
// HTTP request headers as key & value | |
$request_headers = array(); | |
$request_headers['Content-Type'] = "application/x-amz-json-1.1"; | |
$request_headers['Host'] = $host_name; | |
$request_headers['x-amz-date'] = $timestamp; | |
$request_headers['x-amz-target'] = "MTurkRequesterServiceV20170117.GetAccountBalance"; | |
// Sort it in ascending order | |
ksort($request_headers); | |
// Canonical headers | |
$canonical_headers = []; | |
foreach($request_headers as $key => $value) { | |
if(!array_key_exists(strtolower($key), $headerBlacklist)) { | |
$canonical_headers[] = strtolower($key) . ":" . $value; | |
} | |
} | |
$canonical_headers = implode("\n", $canonical_headers); | |
// Signed headers | |
$signed_headers = []; | |
foreach($request_headers as $key => $value) { | |
if(!array_key_exists(strtolower($key), $headerBlacklist)) { | |
$signed_headers[] = strtolower($key); | |
} | |
} | |
$signed_headers = implode(";", $signed_headers); | |
$content = "{}"; | |
// Cannonical request | |
$canonical_request = []; | |
$canonical_request[] = "POST"; | |
$canonical_request[] = "/" ; | |
$canonical_request[] = ""; | |
$canonical_request[] = $canonical_headers; | |
$canonical_request[] = ""; | |
$canonical_request[] = $signed_headers; | |
$canonical_request[] = hash('sha256', $content); | |
$canonical_request = implode("\n", $canonical_request); | |
$hashed_canonical_request = hash('sha256', $canonical_request); | |
// AWS Scope | |
$scope = []; | |
$scope[] = $date; | |
$scope[] = $aws_region; | |
$scope[] = $aws_service_name; | |
$scope[] = "aws4_request"; | |
// String to sign | |
$string_to_sign = []; | |
$string_to_sign[] = "AWS4-HMAC-SHA256"; | |
$string_to_sign[] = $timestamp; | |
$string_to_sign[] = implode('/', $scope); | |
$string_to_sign[] = $hashed_canonical_request; | |
$string_to_sign = implode("\n", $string_to_sign); | |
// Signing key | |
$kSecret = 'AWS4' . $aws_secret_access_key; | |
$kDate = hash_hmac('sha256', $date, $kSecret, true); | |
$kRegion = hash_hmac('sha256', $aws_region, $kDate, true); | |
$kService = hash_hmac('sha256', $aws_service_name, $kRegion, true); | |
$kSigning = hash_hmac('sha256', 'aws4_request', $kService, true); | |
// Signature | |
$signature = hash_hmac('sha256', $string_to_sign, $kSigning); | |
// Authorization | |
$authorization = [ | |
'Credential=' . $aws_access_key_id . '/' . implode('/', $scope), | |
'SignedHeaders=' . $signed_headers, | |
'Signature=' . $signature | |
]; | |
$authorization = 'AWS4-HMAC-SHA256' . ' ' . implode( ',', $authorization); | |
// Curl headers | |
$curl_headers = [ 'Authorization: ' . $authorization ]; | |
foreach($request_headers as $key => $value) { | |
$curl_headers[] = $key . ": " . $value; | |
} | |
$url = 'https://' . $host_name ."/"; | |
$ch = curl_init($url); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | |
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); | |
curl_setopt($ch, CURLOPT_TIMEOUT, 30); | |
curl_setopt($ch, CURLOPT_POST, true); | |
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); | |
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); | |
curl_setopt($ch, CURLOPT_POSTFIELDS, $content); | |
curl_setopt($ch, CURLOPT_VERBOSE, 1); | |
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); | |
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); | |
curl_setopt($ch, CURLOPT_HEADER, false); | |
curl_setopt($ch, CURLINFO_HEADER_OUT, true); | |
curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_headers); | |
$response = curl_exec($ch); | |
$err = curl_error($ch); | |
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); | |
$headers = curl_getinfo($ch, CURLINFO_HEADER_OUT); | |
print("\n\nHeaders:\n"); | |
print_r($headers); | |
print("\n\nHTTP Status:\n"); | |
print($http_code); | |
print("\n\nError:\n"); | |
print_r($err); | |
print("\n\nResponse:\n"); | |
print_r($response); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment