重力形式签名 - 从 PHP 到 Python

Gravity Forms Signature - From PHP to Python

我需要将一些现有的 PHP 代码翻译成 Python。此作业连接到重力表并查询某些数据。为了进行查询,必须计算签名以验证连接。

Gravity Forms 网站 api 给出了很好的 PHP 方向 here

PHP方法如下:

function calculate_signature( $string, $private_key ) {
    $hash = hash_hmac( 'sha1', $string, $private_key, true );
    $sig = rawurlencode( base64_encode( $hash ) );
    return $sig;
}

根据我对Python的理解和php2python.com中关于hash-hmac和rawurlencoded的信息,我写了以下内容:

import hmac, hashlib, urllib, base64
def calculate_signature(string, private_key):
    hash_var = hmac.new(private_key, string, hashlib.sha1).digest()
    sig = urllib.quote(base64.b64encode(hash_var))
    return sig

但是,这两个签名并不等同,因此 Gravity 形成 returns HTTP 403:错误请求响应。

我的翻译是否遗漏了什么?


更新 (11/04/15)

我现在已经匹配了我的 php 和 python 网址。但是,我仍然收到 403 错误。

你快到了。 urllib.quote does not encode slashes, for example, as PHP's rawurlencode does. You can use urllib.quote_plus达到想要的效果:

import hmac, hashlib, urllib, base64
def calculate_signature(string, private_key):
    hash_var = hmac.new(private_key, string, hashlib.sha1).digest()
    sig = urllib.quote_plus(base64.b64encode(hash_var))
    return sig

php 和 python 签名不匹配的原因与他们的 calculate_signature() 方法无关。

问题是由不同的 expires 变量引起的。 Php 使用了 strtotime("+60 mins"),这导致 UTC 时间距现在 60 分钟。而 Python 使用了 datetime.date.now() + timedelta(minutes=60)。这也是距现在 60 分钟,但在您当前的时区。

我一直想在 UTC 中计算 expire 变量,所以我用 datetime.datetime.utcnow() + timedelta(minutes=60) 替换了我的 Python 计算。