I'm trying to call Magento REST API with pre authorized access token, I thought it would be easy but for some reason i cant get it to work, i mean i have the four components required, the consumerKey, consumerSecret, oauth_token and oauth_token_secret, however i always get a nonce_used error (right from the REST docs: This error is used if the nonce-timestamp combination has already been used.)
My normal authentication code is as follows:
class AppFactory_Basic_TestController extends Mage_Core_Controller_Front_Action {
public function indexAction() {
 //Basic parameters that need to be provided for oAuth authentication
 //on Magento
 $params = array(
 'siteUrl' => 'http://www.appfactory.loc/magento/oauth',
 'requestTokenUrl' => 'http://www.appfactory.loc/magento/oauth/initiate',
 'accessTokenUrl' => 'http://www.appfactory.loc/magento/oauth/token',
 'authorizeUrl' => 'http://www.appfactory.loc/magento/admin/oauth_authorize',//This URL is used only if we authenticate as Admin user type
 'consumerKey' => '0165d0443e9a15a019f26b2e2ca8c0bc',//Consumer key registered in server administration
 'consumerSecret' => 'a1e9e199de111a566ed9698da7bf69b2',//Consumer secret registered in server administration
 'callbackUrl' => 'http://www.appfactory.loc/magento/basic/test/callback',//Url of callback action below
 );
 // Initiate oAuth consumer with above parameters
 $consumer = new Zend_Oauth_Consumer($params);
 // Get request token
 $requestToken = $consumer->getRequestToken();
 // Get session
 $session = Mage::getSingleton('core/session');
 // Save serialized request token object in session for later use
 $session->setRequestToken(serialize($requestToken));
 // Redirect to authorize URL
 //Zend_Debug::dump( serialize($requestToken) );
 //Zend_Debug::dump( $requestToken );
 $consumer->redirect();
 return;
}
public function callbackAction() {
 //oAuth parameters
 $params = array(
 'siteUrl' => 'http://www.appfactory.loc/magento/oauth',
 'requestTokenUrl' => 'http://www.appfactory.loc/magento/oauth/initiate',
 'accessTokenUrl' => 'http://www.appfactory.loc/magento/oauth/token',
 'consumerKey' => '0165d0443e9a15a019f26b2e2ca8c0bc',
 'consumerSecret' => 'a1e9e199de111a566ed9698da7bf69b2'
 );
 // Get session
 $session = Mage::getSingleton('core/session');
 // Read and unserialize request token from session
 $requestToken = unserialize($session->getRequestToken());
 // Initiate oAuth consumer
 $consumer = new Zend_Oauth_Consumer($params);
 // Using oAuth parameters and request Token we got, get access token
 Mage::log('Get Array:' . print_r($_GET, true) );
 $acessToken = $consumer->getAccessToken($_GET, $requestToken);
 // Get HTTP client from access token object
 $restClient = $acessToken->getHttpClient($params);
 // Set REST resource URL
 $restClient->setUri('http://www.appfactory.loc/magento/api/rest/products');
 // In Magento it is neccesary to set json or xml headers in order to work
 $restClient->setHeaders('Accept', 'application/json');
 // Get method
 $restClient->setMethod(Zend_Http_Client::GET);
 //Make REST request
 $response = $restClient->request();
 // Here we can see that response body contains json list of products
 Zend_Debug::dump($response);
 return;
}
Everything so far is running smoothly, im getting the Magento Authorize/Deny page and im redirected to the call back function with the actual API output and the product list. Now I try to do another call with the aouth_token i got:
public function doshitAction(){
 $params = array(
 'siteUrl' => 'http://www.appfactory.loc/magento/oauth',
 'requestTokenUrl' => 'http://www.appfactory.loc/magento/oauth/initiate',
 'accessTokenUrl' => 'http://www.appfactory.loc/magento/oauth/token',
 'consumerKey' => '0165d0443e9a15a019f26b2e2ca8c0bc',
 'consumerSecret' => 'a1e9e199de111a566ed9698da7bf69b2'
 );
 // Get session
 $session = Mage::getSingleton('core/session');
 // Read and unserialize request token from session
 $requestToken = unserialize($session->getRequestToken());
 Zend_Debug::dump($requestToken);
 // Initiate oAuth consumer
 $consumer = new Zend_Oauth_Consumer($params);
 // Using oAuth parameters and request Token we got, get access token
 $acessToken = $consumer->getAccessToken( array( 'oauth_token' => 'abd3945f27c4601591cb3434665ad6e8' ,
 'oauth_verifier' => '85516e31405f59ac6f50eabac001edc5'
 ) , $requestToken);
 // do a request
 $restClient = $acessToken->getHttpClient($params);
 $restClient->setUri('http://www.appfactory.loc/magento/api/rest/products');
 $restClient->setHeaders('Accept', 'application/json');
 $restClient->setMethod(Zend_Http_Client::GET);
 $response = $restClient->request();
 // Here we can see that response body contains json list of products
 Zend_Debug::dump($response);
 return;
}
And this is where im stuck, its exactly the same code in the callback function, but i replaced $_GET array with the varaiables that were actually in the array. What i am doing wrong. The $requestToken btw dump is
object(Zend_Oauth_Token_Request)#131 (3) {
 ["_params":protected] => array(3) {
 ["oauth_token"] => string(32) "abd3945f27c4601591cb3434665ad6e8"
 ["oauth_token_secret"] => string(32) "1c06bdd7614dce7357095fb43dd526a7"
 ["oauth_callback_confirmed"] => string(4) "true"
 }
 ["_response":protected] => NULL
 ["_httpUtility":protected] => object(Zend_Oauth_Http_Utility)#44 (0) {
 }
}
so it has the oauth_token and oauth_token_secret, not sure why the getAccessToken functions need a oauth_verifier value.
Below is the stack trace:
Could not retrieve a valid Token response from Token URL:
oauth_problem=nonce_used
Trace:
#0 C:\Development\stage\grantorino-appfactory-ab\magento\lib\Zend\Oauth\Http.php(190): Zend_Oauth_Http->_assessRequestAttempt(Object(Zend_Http_Response))
#1 C:\Development\stage\grantorino-appfactory-ab\magento\lib\Zend\Oauth\Http.php(191): Zend_Oauth_Http->startRequestCycle(Array)
#2 C:\Development\stage\grantorino-appfactory-ab\magento\lib\Zend\Oauth\Http.php(191): Zend_Oauth_Http->startRequestCycle(Array)
#3 C:\Development\stage\grantorino-appfactory-ab\magento\lib\Zend\Oauth\Http\AccessToken.php(52): Zend_Oauth_Http->startRequestCycle(Array)
#4 C:\Development\stage\grantorino-appfactory-ab\magento\lib\Zend\Oauth\Consumer.php(225): Zend_Oauth_Http_AccessToken->execute()
#5 C:\Development\stage\grantorino-appfactory-ab\magento\app\code\local\AppFactory\Basic\controllers\TestController.php(96): Zend_Oauth_Consumer->getAccessToken(Array, Object(Zend_Oauth_Token_Request))
I also tracked the Zend_Oauth_Http_AccessToken and found out that I actually im getting a new nonce on every request:
 /**
 * Initiate a HTTP request to retrieve an Access Token.
 *
 * @return Zend_Oauth_Token_Access
 */
 public function execute()
 {
 $params = $this->assembleParams();
 Zend_Debug::dump($params);
 $response = $this->startRequestCycle($params);
 $return = new Zend_Oauth_Token_Access($response);
 return $return;
 }
/**
 * Assemble all parameters for an OAuth Access Token request.
 *
 * @return array
 */
public function assembleParams()
{
 $params = array(
 'oauth_consumer_key' => $this->_consumer->getConsumerKey(),
 'oauth_nonce' => $this->_httpUtility->generateNonce(),
 'oauth_signature_method' => $this->_consumer->getSignatureMethod(),
 'oauth_timestamp' => $this->_httpUtility->generateTimestamp(),
 'oauth_token' => $this->_consumer->getLastRequestToken()->getToken(),
 'oauth_version' => $this->_consumer->getVersion(),
 );
 if (!empty($this->_parameters)) {
 $params = array_merge($params, $this->_parameters);
 }
 $params['oauth_signature'] = $this->_httpUtility->sign(
 $params,
 $this->_consumer->getSignatureMethod(),
 $this->_consumer->getConsumerSecret(),
 $this->_consumer->getLastRequestToken()->getTokenSecret(),
 $this->_preferredRequestMethod,
 $this->_consumer->getAccessTokenUrl()
 );
 return $params;
}
so the error message showing might be misleading.
1 Answer 1
I was simply using the wrong oauth_token_secret, i should have used the one returned from the access_token not the request_token.
On another note the oauth_verifier is not needed when accessing the api endpoints.
Thats how the function ended up:
public function doshitAction(){
$params = array(
 'siteUrl' => 'http://www.appfactory.loc/magento/oauth',
 'requestTokenUrl' => 'http://www.appfactory.loc/magento/oauth/initiate',
 'accessTokenUrl' => 'http://www.appfactory.loc/magento/oauth/token',
 'consumerKey' => '531a7d194914fbd207766bcb022cdc94',
 'consumerSecret' => 'f51868e362b9211d4fde5ebf412080b0',
 'requestScheme' => Zend_Oauth::REQUEST_SCHEME_HEADER
);
// Initiate oAuth consumer
$consumer = new Zend_Oauth_Consumer($params);
// Using oAuth parameters and request Token we got, get access token
$acessToken = new Zend_Oauth_Token_Access;
$acessToken->setParams(array(
 'oauth_token' => 'e3d089e2b420cd3b940c3cf67587a95d',
 'oauth_token_secret' => 'ab2f46861defe6ee5740f7a748301367'
));
// do a request
$restClient = $acessToken->getHttpClient($params);
$restClient->setUri('http://www.appfactory.loc/magento/api/rest/products');
$restClient->setHeaders('Accept', 'application/json');
$restClient->setMethod(Zend_Http_Client::GET);
$response = $restClient->request();
// Here we can see that response body contains json list of products
return $response->getBody();
}