Skip to content

Instantly share code, notes, and snippets.

@anjesh
Last active August 9, 2022 00:01
Show Gist options
  • Save anjesh/3d5ec6bfde0b12a8e91f435a9e07ea97 to your computer and use it in GitHub Desktop.
Save anjesh/3d5ec6bfde0b12a8e91f435a9e07ea97 to your computer and use it in GitHub Desktop.
Mturk working code for `GetAccountBalance` with signature generation
<?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