如果有人问过这个问题或有类似问题,我深表歉意;我已经使用不同的搜索词搜索了几天,结果都是空的。
我有一个 python 脚本,可以正常工作。我将它安装在我的 Windows 机器上并在本地运行脚本。我想要做的是以某种方式将其转换为 PHP 请求;我认为 cURL 将是选择的选项,但我愿意接受建议。我已经进行了几次尝试,但我不断收到身份验证错误。我相信这很简单;但也许不是。
这是我的python脚本:
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()
这是我的测试 PHP 代码:
<?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;
?>
请注意,时间戳必须存储在一个变量中,以便在 HMAC 中散列并作为标头发送,否则肯定不会进行身份验证。
任何指导或建议将不胜感激!
谢谢
答案 0 :(得分:1)
如果您只要求此 api 调用工作,那么我建议您只重新创建请求,而不是尝试翻译它。您可以设置环境变量等,然后使用 Postman 等工具下载 cURL 代码。
如果您要的是一种以编程方式进行切换的方法,我从未见过这样做的方法。
答案 1 :(得分:1)
我有一位同事指出了我的问题。对于任何有兴趣的人..
我有两个问题导致它失败。第一个是我在 cURL 标头中缺少授权字符串的前置部分:
loc
第二个问题是,根据python脚本和文档,它需要进行base64编码。所以 'authorization: AttAPI '.$api_key.':'.genAuthString($secret_key, $uri, $timestamp),
的返回行应该是:
genAuthString()
答案 2 :(得分:0)
我知道重新编码很难。如果你想在 PHP 中毫无问题地发出 http 请求,我建议你试试 Guzzle