Мне нужно перевести некоторый существующий код PHP на Python. Эта работа связана с гравитационными формами и запросами определенных данных. Чтобы сделать запрос, необходимо проверить подпись для проверки соединения.
Веб-интерфейс Gravity Forms дает хорошие направления PHP Вот.
Метод PHP выглядит следующим образом:
function calculate_signature( $string, $private_key ) {
$hash = hash_hmac( 'sha1', $string, $private_key, true );
$sig = rawurlencode( base64_encode( $hash ) );
return $sig;
}
Основываясь на моем понимании Python и информации о hash-hmac и rawurlencoded от php2python.com, я написал следующее:
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 Forms возвращает HTTP 403: неправильный запрос.
Я что-то упустил в моем переводе?
Обновление (11/04/15)
Теперь я сопоставил свои php и python URL. Тем не менее, я все еще получаю ошибку 403.
Причина, по которой подписи php и python не совпадают, не имеет ничего общего с их calculate_signature()
методы.
Проблема была вызвана различными expires
переменные. Php используется strtotime("+60 mins")
что привело к времени UTC через 60 минут. В то время как Python используется datetime.date.now() + timedelta(minutes=60)
, Это также через 60 минут, но в вашем текущем часовом поясе.
Я всегда хочу рассчитать expire
переменная в UTC, поэтому я заменил мой расчет Python на datetime.datetime.utcnow() + timedelta(minutes=60)
,
Ты почти там. urllib.quote
не кодирует косую черту, например, как PHP rawurlencode
делает. Ты можешь использовать 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