Как подписать полезную нагрузку закрытым ключом в PHP?

1

Я пытаюсь использовать GoodRx API с помощью PHP.

Вот мой код:

 $hash = hash_hmac('sha256', $query_string, MY_SECRET_KEY);
 $encoded = base64_encode($hash);
 $private_key = str_replace('+', '_', $encoded);
 $private_key = str_replace('/', '_', $encoded);
 //$private_key = urlencode($private_key);
 $query_string .= '&sig=' . $private_key;

 echo $query_string;    
 // https://api.goodrx.com/low-price?name=Lipitor&api_key=MY_API_KEY&sig=MY_SECRET_KEY

Он возвращает ошибку, говоря, что мой sig не прав.

Не могли бы вы мне помочь, пожалуйста.

Спасибо.

Томас.

Теги:
rest
signing

2 ответа

2

Проводка этого в случае, если кому-то нужен полный пример того, как сделать основной вызов API GoodRx:

В Python:

import requests
import hashlib
import hmac
import base64

# python --version returns:
#        Python 3.5.1 :: Anaconda 2.4.1 (32-bit)

# my_api_key is the API key for your account, provided by GoodRx
my_api_key = "YOUR_API_KEY";

# s_skey is the secret key for your account, provided by GoodRx
my_secret_key=str.encode("YOUR_SECRET_KEY", 'utf-8')

# Create the base URL and the URL parameters
# The url_params start as text and then have to be encoded into bytes
url_base = "https://api.goodrx.com/fair-price?"
url_params = str.encode("name=lipitor&api_key=" + my_api_key, 'utf-8')

# This does the hash of url_params with my_secret_key    
tmpsig = hmac.new(my_secret_key, msg=url_params,     digestmod=hashlib.sha256).digest()

# Base64 encoding gets rid of characters that can't go in to URLs. 
# GoodRx specifically asks for these to be replaced with "_"
sig = base64.b64encode(tmpsig, str.encode("__", 'utf-8') )    

# Convert the sig back to ascii
z = sig.decode('ascii')

# add the sig to the URL base
url_base += url_params.decode('ascii') + "&sig=" + z

# request the URL base
r = requests.get(url_base)

# print the response
print(r.content)

Вы должны получить что-то вроде этого для вывода:

{"errors": [], "data": {"mobile_url": " http://m.goodrx.com/?grx_ref=api#/drug/atorvastatin/tablet ", "form": "tablet", " url ":" http://www.goodrx.com/atorvastatin?grx_ref=api "," brand ": [" lipitor "]," dosage ":" 20mg "," price ": 12.0," generic ": [ "atorvastatin"], "количество": 30, "display": "Lipitor (atorvastatin)", "производитель": "generic"}, "success": true}

Вот аналогичный код на PHP, глядя на наркотик Апидра Солостар, у которого есть NDC 00088250205:

<?php
function base64url_encode($data) { 
    return strtr(base64_encode($data), '+/', '__'); 
} 

$my_api_key = "YOUR_API_KEY";
$s_key="YOUR_SECRET_KEY";
$ndc = "00088250205";

// Initialize the CURL package. This is the thing that sends HTTP requests
$ch = curl_init();

// Create the URL and the hash
$url = "https://api.goodrx.com/fair-price?";

$query_string="ndc=" . $ndc . "&api_key=" . $my_api_key;

$tmp_sig = hash_hmac('sha256', $query_string, $s_key, true);
$sig = base64url_encode( $tmp_sig );

$url = $url . $query_string . "&sig=" . $sig;

// set some curl options
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_VERBOSE, true);

// run the query
$response = curl_exec($ch);

var_dump($response);
?>

Спасибо Томасу за то, что поговорили со мной по этому поводу.

  • 0
    Большое спасибо, что нашли время, чтобы сделать это, Лен! Ничто не сравнится с «полным примером».
2

Вы неправильно выполняете свои строковые замены:

$private_key = str_replace('+', '_', $encoded);
   ^^---new string                       ^---original string
$private_key = str_replace('/', '_', $encoded);
   ^--overwrite previous replacement     ^---with original string again

Если вы хотите заменить цепочку, вам нужно сделать что-то большее:

$orig = 'foo';
$temp = str_replace(..., $orig);
$temp = str_replace(..., $temp);
...
$final = str_replace(..., $temp);

Обратите внимание, как вы передаете результат предыдущей замены в следующий вызов, чего вы не делаете. Вы просто продолжаете брать оригиналы tring, заменяете одну вещь, а затем уничтожаете эту замену при следующем вызове. Таким образом, вы ТОЛЬКО выполняете замену /_ и отправляете + as-is.

  • 0
    Я сделал исправление, как вы предложили, но все равно получил ошибку.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню