I apologize if this has been asked or has a similar questions; I have been searching for days using different search terms and have come up empty.
I have a python script that works perfectly fine as expected. I have it installed on my windows machine and run the script locally. What I want to do is somehow convert this to a PHP request; I assumed cURL would be the option selected but I am open to suggestions. I have made a couple attempts on my end, but I keep getting an authentication error. I'm sure it's something simple; but maybe not.
Here is my python script:
import requests
from datetime import datetime
import hashlib
import hmac
import base64
import json
import time
def main():
api_key = 'abcd'
secret_key = 'hashedSecret'
host = 'https://myapidomain.com/'
uri = 'api/1.0/Projects/8030854199/items'
http_verb = 'GET'
content_type = 'application/json'
timestamp = gen_iso_timestamp()
auth_header_value = gen_auth_string(api_key, secret_key, uri, http_verb, content_type, timestamp)
full_url = f'{host}{uri}'
headers = {'att-api-timestamp': timestamp, 'authorization': auth_header_value, 'Content-Type': content_type, 'Accept': content_type}
r = requests.get(full_url, headers=headers)
if r.status_code == 200:
with open(f'data_dump/8030854199.json', 'w+') as json_file:
json_file.write(r.text)
elif r.status_code != 200:
error_code = f'{r.status_code}'
with open(f'data_dump/error.txt', 'w+') as json_file:
json_file.write(error_code)
def gen_auth_string(api_key, secret_key, uri, http_verb, content_type, timestamp):
message = f'{http_verb}\n{content_type}\n{uri}\n{timestamp}'
canonical_request = bytes(message, 'ASCII')
secret_bytes = bytes(secret_key, 'ASCII')
digest = hmac.new(secret_bytes, msg=canonical_request, digestmod=hashlib.sha256).digest()
signature = base64.b64encode(digest).decode()
return f'AttAPI {api_key}:{signature}'
def gen_iso_timestamp():
# generate a timestamp in this format 2018-12-31T23:55:55+00:00
return f'{datetime.utcnow().replace(microsecond=0).isoformat()}+00:00'
if __name__ == "__main__":
main()
Here was my test PHP code:
<?php
function genTimestamp(){ return gmdate(DATE_ATOM); }
function genAuthString($secret_key, $uri, $timestamp){
$message = "GET"."\n"."application/json"."\n".$uri."\n".$timestamp;
return hash_hmac('sha256',$message,$secret_key,true);
}
$api_key = 'abcd';
$secret_key = 'hashedSecret';
$host = 'https://myapidomain.com/';
$uri = 'api/1.0/Projects/8030854199/items';
$timestamp = genTimestamp();
// for testing:
// echo $timestamp."<br />";
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $host.$uri);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
// for testing:
// echo genAuthString($secret_key, $uri, $timestamp)."<br />"
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'att-api-timestamp: '.$timestamp,
'authorization: '.genAuthString($secret_key, $uri, $timestamp),
'Content-Type: application/json',
'Accept: application/json'
));
// for testing:
// echo "Executing... <br />";
$result = curl_exec($curl);
if (curl_errno($curl)) {
// for testing:
echo 'Error:' . curl_error($curl) . "<br />";
}
curl_close($curl);
echo $result;
?>
Note that the timestamp must be stored in a variable to be hashed in the HMAC and sent as a header or else it definitely won't authenticate.
Any guidance or suggestions would be greatly appreciated!
Thanks