ЗДЕСЬ REST API OAuth 2.0 Token Request (с заголовком 1.0) Ошибка - PullRequest
0 голосов
/ 08 марта 2020

Я пытался заставить мое приложение PHP создать успешный запрос токена, так как, наконец, удалось заставить его работать с Postman согласно документам здесь

Видимо API использует OAuth 2.0, поэтому я ожидаю отправки grant_type, client_id, client_secret и expires_in (если я не укажу одно из этих полей, API успешно сообщит мне, что оно отсутствует).

Теперь у меня проблема с этим заголовком авторизации OAuth 1.0, который мне нужно сгенерировать, и у Почтальона, похоже, нет проблем с этим, однако при попытке сделать это в PHP Я просто получаю Ошибка API, возвращенная из-за несоответствия подписи:

array:6 [
  "errorId" => "ERROR-fde4f0f1-9d5c-43fd-80eb-056cbf2c3259"
  "httpStatus" => 401
  "errorCode" => 401300
  "message" => "Signature mismatch. Authorization signature or client credential is wrong."
  "error" => "invalid_client"
  "error_description" => "errorCode: '401300'. Signature mismatch. Authorization signature or client credential is wrong."
]

Я пробовал различные способы отладки, многие из которых приводят к разным ошибкам, но я продолжаю возвращаться к этой, поэтому проблема должна быть в подписи.

Я создал следующий класс здесь для обработки генерации заголовка и получения некоторых указаний от класса в пакете guzzle/oauth-subscriber.

Вот пример Пример сгенерированных заголовков запроса:

array:2 [
  "Content-Type" => "application/x-www-form-urlencoded"
  "Authorization" => "OAuth oauth_consumer_key="XXXXXXXXXXXX",oauth_signature_method="HMAC-SHA256",oauth_timestamp="1583629976",oauth_nonce="Br2HsCVzsaEe3KswBhtCzsSxjUDWgX56",oauth_version="1.0",oauth_signature="G7%2B5f2v2Kdx3rp%2B28DcuJRBvhi9H7fHC1mFLqJIgmMc%3D""
]

И тело запроса:

array:4 [
  "grant_type" => "client_credentials"
  "client_id" => "XXXXXXXXXXXX"
  "client_secret" => "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
  "expires_in" => 87000
]

Заменены важные данные, но consumer_key является верным и соответствует значению client_id и то же самое относится к consumer_secret и client_secret

Независимо от того, как я пытаюсь изменить метод signUsingHmac() для изменения подписи, он не работает, и все это выглядит хорошо для меня D:

У кого-нибудь есть какие-нибудь идеи?

Если я смогу заставить это работать хорошо, я вытащу его в пакет, чтобы сделать аутентификацию для этого API в PHP намного менее болезненной.

РЕДАКТИРОВАТЬ:

Я попытался сформировать подпись в точности так, как показано в документах здесь , но, к сожалению, это все еще не сработало, вот как выглядел мой $baseString при переходе в ха sh метод:

POST&https%3A%2F%2Faccount.api.here.com%2Foauth2%2Ftoken&grant_type%3Dclient_credentials%26oauth_consumer_key%3DXXbXbXbXbXbXbXb%26oauth_nonce%3DrZNNSZGOOIHFFtLboCjdAheCmKJmOYSp%26oauth_signature_method%3DHMAC-SHA256%26oauth_timestamp%3D1583640503%26oauth_version%3D1.0

Я также создал новый гист здесь с моими обновлениями для создания этого $baseString

Cheers, Matt

Ответы [ 2 ]

1 голос
/ 15 марта 2020

Я создал суть, которая работает. Некоторые предложения:

  • все значения должны быть urlenconde ()
  • строка, которую необходимо использовать для подписи, запрос должен включать: метод (прописными буквами) и URL (код ссылки) & список параметров (в кодировке url)
  • ключ подписи - это секретный ключ вашего ключа (urlencode) , за которым следует & . Это потому, что обычно ваш ключ подписи должен быть секретным и секретным токеном. В этом случае у нас нет секретного токена

Для списка параметров для вашей базовой строки сигнатуры вам нужно включить все параметры oauth_ и ваш grant_type, потому что вам нужно включить также параметр body. Сортировка этих ключей очень важна

некоторый код PHP код:

$keyId = getenv('HERE_API_KEY_ID');
$keySecret = getenv('HERE_API_KEY_SECRET');

$httpBody = [
    "grant_type" => "client_credentials"
];
$httpMethod = "POST";
$httpUrl = 'https://account.api.here.com/oauth2/token';


$oauthNonce = mt_rand();
$oauthTimestamp = time();
$oauthSignatureMethod= "HMAC-SHA256";
$oauthVersion = "1.0";


$baseString = $httpMethod."&". urlencode($httpUrl);

$oauth1Param = [
    'oauth_consumer_key' => $keyId,
    'oauth_signature_method' => $oauthSignatureMethod,
    'oauth_timestamp' => $oauthTimestamp,
    'oauth_nonce' => $oauthNonce,
    'oauth_version' => $oauthVersion
];


$paramString =

        "grant_type=client_credentials&".
        "oauth_consumer_key=". urlencode($oauth1Param['oauth_consumer_key']).
        "&oauth_nonce=". urlencode($oauth1Param['oauth_nonce']).
        "&oauth_signature_method=". urlencode($oauth1Param['oauth_signature_method']).
        "&oauth_timestamp=". urlencode($oauth1Param['oauth_timestamp']).
//        "&oauth_token=".
        "&oauth_version=". urlencode($oauth1Param['oauth_version'])
;

echo $paramString.PHP_EOL;
$baseString = $baseString . "&" . urlencode($paramString);
echo $baseString . PHP_EOL;
$signingKey= urlencode($keySecret) . "&";
$signature = urlencode(
    base64_encode(
    hash_hmac(
        'sha256',
        $baseString,
        $signingKey,
        true
    )
    )
);

$oauth1Param['oauth_signature']  =  $signature;
echo "RUNTIME SIGNATURE : " . $signature .PHP_EOL;

Я создаю работающий GIST, единственное, что вам нужно изменить, это $ keyId и $ keySecret , https://gist.github.com/roberto-butti/736c38c796ede70c719f6a21a752c971

Эта документация была очень полезной: https://developer.twitter.com/en/docs/basics/authentication/oauth-1-0a/creating-a-signature

0 голосов
/ 09 марта 2020

Кажется, что access_id и access_key передаются в теле запроса, "grant_type" => "client_credentials" должен быть только в теле, а access_id and access_key должен передаваться в заголовке. Вы можете сначала попробовать это в почтальоне, если это сработает, пожалуйста, верните

...