我有一个简短的CURL脚本,我正在尝试转换为Python,但我遇到了这么多麻烦。我的目标是一个需要格式为<public_key>.<sha256 hmac of url and body>
的身份验证字符串的API。
我的遗留设置是一个简单的PHP脚本,它生成hmac并使用输出运行CURL命令。我正在尝试将其移植到Python以获得单独的项目。
传统代码:
hmac.php
<?php
$public = 'PUBLIC_KEY';
$private = 'PRIVATE_KEY';
$url = $argv[1];
$body = $argv[2];
$hmac = hash_hmac('sha256', $url . $body, $private, true);
print($public . '.' . base64_encode($hmac));
示例命令:
$ DATA='{"command": "say Just testing the API, ignore this..."}'
$ URL='https://website.url/api/user/<UUID>/command'
$ curl -X POST -d $DATA -H "Content-Type: application/json" -H "Authorization: Bearer $(php hmac.php $URL $DATA)" --url $URL
Python端口
到目前为止,我已经找到了如何为GET请求创建正确的hmac摘要,但是我在上面详述的POST请求时遇到了问题。
send_command.py:
def generate_bearer(pubkey, privkey, url, body):
h = hmac.new(privkey.encode('utf8'), (url + body).encode('utf8'), sha256)
encoded = b64encode(h.digest())
return pubkey + '.' + encoded.decode('utf-8')
def send_command(server, command):
target = '{}/server/{}/command'.format(url, server)
data = {'command': command}
bearer = generate_bearer(public, private, target, str(data))
headers = {'Authorization': 'Bearer {}'.format(bearer),
'content-type': 'application/json'}
r = requests.post(target, headers=headers, data=data)
if __name__ == '__main__':
print(send_command('<UUID>', 'say Just testing the API, ignore this...'))
据我所知,我需要将完整的JSON字符串传递给generate_bearer()
,并将其作为我在请求中POST的数据。但是,使用此当前代码,我收到错误“请求的HMAC无效”。我在这里做错了什么?
答案 0 :(得分:1)
很难说出你所描述的问题可能是什么。此API是否公开,以便其他人可以测试并获得更好的帮助?
我正在比较PHP与Python代码,并注意到您不遵循相同模式的URL:
但由于这些例子不完整或脱离了背景,因此很难说清楚。
答案 1 :(得分:0)
经过一些实验,我发现了它。将数据dict传递给散列函数时,我使用的是str(data)
。我为哈希和请求切换到json.dumps(data)
,现在一切正常。
新代码如下所示:
def send_command(server, command):
target = '{}/server/{}/command'.format(url, server)
d = {'command': command}
bearer = generate_bearer(public, private, target, json.dumps(d))
h = {'Authorization': 'Bearer {}'.format(bearer),
'content-type': 'application/json'}
r = requests.post(target, headers=h, data=json.dumps(d))
return r.text
答案 2 :(得分:0)
我采用了示例here并将其转换为Python,如下所示:
import hmac
import hashlib
import base64
public = 'JkAFq7M47kLN0xVD';
private = 'E6X9FyZvMFeJbqtq.IwjlTuR.MKDoicB';
url = 'http://pterodactyl.app/api/admin/users';
body = '';
dig = hmac.new(private, msg='{}{}'.format(url, body), digestmod=hashlib.sha256).digest()
print '{}.{}'.format(public, base64.b64encode(dig).decode()),
返回与PHP代码相同的输出:JkAFq7M47kLN0xVD.wgIxj + V8RHgIetcQg2lRM0PRSH / y5M21cPz9zVhfFaQ