Change some headers on each retry to reflect date and time and request signature
stoufa06 opened this issue · comments
Detailed description
I have used this package to resolve a problem of some failed requests but i got other errors when when retrying to send same request to garmin api server using League\OAuth1 package.
Make it clear if the issue is a bug, an enhancement or just a question.
This is probably not an issue for most of users but it is very important to have a way to change request headers when retying for many seconds if the api requires timestamp and signature to be up to date for authentication.
Received error [{
"message" : "Invalid nonce and timestamp",
"error" : "The request has not been applied because it lacks valid authentication credentials for the target resource."
}
The oauth_nonce and oauth_timestamp and oauth_signature headers needs to be updated for each request
/**
* Get the base protocol parameters for an OAuth request.
* Each request builds on these parameters.
*
* @see OAuth 1.0 RFC 5849 Section 3.1
*/
protected function baseProtocolParameters(): array
{
$dateTime = new DateTime('now', new DateTimeZone('UTC'));
return [
'oauth_consumer_key' => $this->clientCredentials->getIdentifier(),
'oauth_nonce' => $this->nonce(),
'oauth_signature_method' => $this->signature->method(),
'oauth_timestamp' => $dateTime->format('U'),
'oauth_version' => '1.0',
];
}
/**
* Generate the OAuth protocol header for requests other than temporary
* credentials, based on the URI, method, given credentials & body query
* string.
*
* @param string $method
* @param string $uri
* @param CredentialsInterface $credentials
* @param array $bodyParameters
* @return string
*/
protected function protocolHeader(string $method, string $uri, CredentialsInterface $credentials, array $bodyParameters = array()): string
{
$parameters = array_merge(
$this->baseProtocolParameters(),
$this->additionalProtocolParameters(),
array(
'oauth_token' => $credentials->getIdentifier(),
),
$bodyParameters
);
$this->signature->setCredentials($credentials);
$parameters['oauth_signature'] = $this->signature->sign(
$uri,
array_merge($parameters, $bodyParameters),
$method
);
return $this->normalizeProtocolParameters($parameters);
}
Hi @stoufa06, I think this is a great use-case for the on-retry callback.
$listener = function($attemptNumber, $delay, &$request, &$options, $response) use (/* whatever */) {
$request = $request->withHeader('oauth_nonce', '[NONCE_VALUE]')
->withHeader('oauth_signature', '[SIGNATURE_VALUE]')
->withHeader('oauth_timestamp', [TIMESTAMP_HERE]');
}
$client = new \GuzzleHttp\Client([
'on_retry_callback' => $listener
// other options as desired...
]);
// Send your requests here!