Consuming Magento REST service using Zend_OAuth_Consumer

Ok folks. Until today, trying to cover this area completely, I wrote two articles about Magento oAuth and REST services:

This Magento REST and oAuth functionality and ways on which it could be used are so wide that I think that even in this three articles will not cover everything that I wanna share with you, so stay tuned for next articles about this topic in near future 🙂

In official Magento documentation, one plain PHP class is written on how to authenticate with oAuth and how to Consume Magento REST web service.
Here I am going to show how you can do it from inside your Magento controller that is acting as REST client this time. Of course, for simplicity, I am not going to handle errors in examples and I am going to consume REST on same Magento installation, but I think that it will be enough to show the point.
Let’s start.

  1. Configure your local Magento installation following last article steps: How to configure Magento REST and oAuth settings
  2. Create Magento controller class in your test module.
  3. Paste source code inside your controller to look like this:
<?php
 
/**
*
* @author Darko Goleš <darko.goles@inchoo.net>
* @package Inchoo
* @subpackage RestConnect
*
* Url of controller is: http://magento.loc/restconnect/test/[action]
*/
class Inchoo_RestConnect_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://magento.loc/oauth',
'requestTokenUrl' => 'http://magento.loc/oauth/initiate',
'accessTokenUrl' => 'http://magento.loc/oauth/token',
'authorizeUrl' => 'http://magento.loc/admin/oAuth_authorize',//This URL is used only if we authenticate as Admin user type
'consumerKey' => 'h7n8qjybu78cc3n8cdd5dr7ujtl33uqh',//Consumer key registered in server administration
'consumerSecret' => '2smfjx37a6e4w23jlcrya6iyv5v32fxr',//Consumer secret registered in server administration
'callbackUrl' => 'http://magento.loc/restconnect/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
$consumer->redirect();
 
return;
}
 
public function callbackAction() {
 
//oAuth parameters
$params = array(
'siteUrl' => 'http://magento.loc/oauth',
'requestTokenUrl' => 'http://magento.loc/oauth/initiate',
'accessTokenUrl' => 'http://magento.loc/oauth/token',
'consumerKey' => 'h7n8qjybu78cc3n8cdd5dr7ujtl33uqh',
'consumerSecret' => '2smfjx37a6e4w23jlcrya6iyv5v32fxr'
);
 
// 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
$acessToken = $consumer->getAccessToken($_GET, $requestToken);
// Get HTTP client from access token object
$restClient = $acessToken->getHttpClient($params);
// Set REST resource URL
$restClient->setUri('http://magento.loc/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;
}
 
}

Now open the indexAction of this controller inside your browser. If everything configured correctly, you should be able to get list of products. At my Magento installation, URL is: http://magento.loc/restconnect/test

oAuthLogin1

oAuthAuthorize

Let’s explain above steps a little bit:

  • First we had to define basic neccesary oAuth parameters for Zend_OAuth_Client.
  • After initiating the client, first we get RequestToken. After request token is retreived, we save it into the session for usage in callback action later.
  • Then we call $client->redirect action and we are redirected to the server user login screen.
  • After successful login, we are redirected to Authorize URL in order user to Authorize application.
  • After authorization, server redirects to our callbackUrl we defined in $params. Here we are getting the RequestToken from session and requesting the AccessToken.
  • After AccessToken is retreived from server, oAuth dance is finished and we are preparing the Http client for making the REST request.
  • We make REST request to server resource URL and retreiving the response

Better way

Uf, let me share something more with you dear visitors:
In the meantime I investigated how to power up Magento oAuth, I developed one Model that can be used ro perform above operations even simpler and cleaner from inside your controller, and I wanna share it with you here.

<?php
/**
*
* @author Darko Goleš <darko.goles@inchoo.net>
* @package Inchoo
* @subpackage RestConnect
*/
class Inchoo_RestConnect_Model_Oauth_Client extends Mage_Core_Model_Abstract
{
private $_callbackUrl;
private $_siteUrl;
private $_consumerKey;
private $_consumerSecret;
private $_requestTokenUrl;
private $_accessTokenUrl;
private $_consumer;
private $_authorizeUrl;
private $_userAuthorizationUrl;
 
private $_authorized_token;
 
const OAUTH_STATE_NO_TOKEN = 0;
const OAUTH_STATE_REQUEST_TOKEN = 1;
const OAUTH_STATE_ACCESS_TOKEN = 2;
const OAUTH_STATE_ERROR = 3;
 
public function init($config)
{
$this->setOAuthConfig($config);
return $this;
}
 
public function setAuthorizedToken($token)
{
$this->_authorized_token = $token;
}
 
public function getAuthorizedToken()
{
if ($this->_authorized_token) {
return $this->_authorized_token;
}
return false;
}
 
public function reset()
{
return $this->resetSessionParams();
}
 
public function authenticate()
{
$state = $this->getOAuthState();
$consumer = $this->_getOAuthConsumer();
 
try {
switch ($state) {
case self::OAUTH_STATE_NO_TOKEN:
$requestToken = $this->getRequestToken();
$this->setOAuthState(self::OAUTH_STATE_REQUEST_TOKEN);
$consumer->redirect();
return self::OAUTH_STATE_REQUEST_TOKEN;
break;
 
case self::OAUTH_STATE_REQUEST_TOKEN:
$accessToken = $this->getAccessToken($this->getRequestToken());
$this->setAuthorizedToken($accessToken);
$this->setOAuthState(self::OAUTH_STATE_ACCESS_TOKEN);
return self::OAUTH_STATE_ACCESS_TOKEN;
break;
case self::OAUTH_STATE_ACCESS_TOKEN:
return self::OAUTH_STATE_ACCESS_TOKEN;
default:
$this->resetSessionParams();
return self::OAUTH_STATE_NO_TOKEN;
return;
break;
}
 
} catch (Zend_Oauth_Exception $e) {
$this->resetSessionParams();
Mage::logException($e);
} catch (Exception $e) {
Mage::logException($e);
}
return self::OAUTH_STATE_NO_TOKEN;
}
 
private function resetSessionParams()
{
$this->getSession()->unsetData('o_auth_state');
$this->getSession()->unsetData('request_token');
$this->getSession()->unsetData('o_auth_config');
$this->getSession()->unsetData('access_token');
 
return $this;
}
 
public function getRequestToken()
{
$token = $this->_getRequestTokenFromSession();
if ($token && $token instanceof Zend_Oauth_Token_Request) {
return $token;
}
 
$token = $this->_getRequestTokenFromServer();
if ($token && $token instanceof Zend_Oauth_Token_Request) {
$this->_saveRequestTokenInSession($token);
return $token;
}
 
return false;
}
 
public function getAccessToken($requestToken)
{
$token = $this->_getAccessTokenFromSession();
if ($token && $token instanceof Zend_Oauth_Token_Access) {
return $token;
}
 
$token = $this->_getAcessTokenFromServer($requestToken);
if ($token && $token instanceof Zend_Oauth_Token_Access) {
$this->_saveAccessTokenInSesion($token);
return $token;
}
}
 
private function _getAcessTokenFromServer($requestToken)
{
if ($requestToken && $requestToken instanceof Zend_Oauth_Token_Request) {
$accToken = $this->_getOAuthConsumer()->getAccessToken(
$_GET,
$requestToken
);
}
 
if ($accToken && $accToken instanceof Zend_Oauth_Token_Access) {
return $accToken;
}
 
return false;
}
 
private function _saveAccessTokenInSesion($accessToken)
{
$this->getSession()->setAccessToken(serialize($accessToken));
}
 
private function _getAccessTokenFromSession()
{
$accessToken = unserialize($this->getSession()->getAcessToken());
if ($accessToken && $accessToken instanceof Zend_Oauth_Token_Access) {
return $accessToken;
}
return false;
}
 
private function _getRequestTokenFromServer()
{
$token = $this->_getOAuthConsumer()->getRequestToken();
return $token;
}
 
private function _saveRequestTokenInSession(Zend_Oauth_Token_Request $requestToken)
{
$this->getSession()->setRequestToken(serialize($requestToken));
}
 
private function _getRequestTokenFromSession()
{
$requestToken = unserialize($this->getSession()->getRequestToken());
if ($requestToken && $requestToken instanceof Zend_Oauth_Token_Request) {
return $requestToken;
}
return false;
}
 
public function getSession()
{
return Mage::getSingleton('core/session');
}
 
public function getOAuthToken()
{
return $this->getRequest()->getParam('oauth_token', false);
}
 
public function getRequest()
{
return Mage::app()->getRequest();
}
 
private function _getOAuthConsumer()
{
if ($consumer = $this->_consumer) {
if ($consumer instanceof Zend_Oauth_Consumer) {
return $this->_consumer;
}
}
$this->_consumer = new Zend_Oauth_Consumer($this->getOAuthConfig());
return $this->_consumer;
}
 
private function getOAuthConfig()
{
$config = array(
'callbackUrl' => $this->_callbackUrl,
'siteUrl' => $this->_siteUrl,
'consumerKey' => $this->_consumerKey,
'consumerSecret' => $this->_consumerSecret,
'requestTokenUrl' => $this->_requestTokenUrl,
'accessTokenUrl' => $this->_accessTokenUrl,
);
 
if ($this->_authorizeUrl && $this->_authorizeUrl != '') {
$config['authorizeUrl'] = $this->_authorizeUrl;
}
 
if ($this->_userAuthorizationUrl && $this->_userAuthorizationUrl != '') {
$config['userAuthorizationUrl'] = $this->_userAuthorizationUrl;
}
 
return $config;
 
}
 
private function setOAuthConfig($config)
{
$this->getSession()->setOAuthConfig(serialize($config));
foreach ($config as $key => $val) {
$_key = '_' . $key;
$this->$_key = $val;
}
}
 
public function getConfigFromSession()
{
$config = unserialize($this->getSession()->getOAuthConfig());
if ($config && is_array($config)) {
return $config;
}
return false;
}
 
private function setOAuthState($state)
{
$this->getSession()->setOAuthState($state);
}
 
public function getOAuthState()
{
$state = $this->getSession()->getOAuthState();
if ($state == null) {
return self::OAUTH_STATE_NO_TOKEN;
}
 
$paramOAuthToken = $this->getOAuthToken();
if ($paramOAuthToken == false && $state == self::OAUTH_STATE_REQUEST_TOKEN) {
$this->resetSessionParams();
return self::OAUTH_STATE_NO_TOKEN;
}
 
return $state;
 
}
 
}

Create your own Model file inside your extension dir, and paste above source code there (of course, don’t forget to rename the class to fit your needs).

After that, you just need to have controller like this:

<?php
 
/**
*
* @author Darko Goleš <darko.goles@inchoo.net>
* @package Inchoo
* @subpackage RestConnect
*
* Url of controller is: http://magento.loc/restconnect/test/[action]
*/
class Inchoo_RestConnect_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://magento.loc/oauth',
'requestTokenUrl' => 'http://magento.loc/oauth/initiate',
'accessTokenUrl' => 'http://magento.loc/oauth/token',
'authorizeUrl' => 'http://magento.loc/admin/oAuth_authorize', //This URL is used only if we authenticate as Admin user type
'consumerKey' => 'h7n8qjybu78cc3n8cdd5dr7ujtl33uqh', //Consumer key registered in server administration
'consumerSecret' => '2smfjx37a6e4w23jlcrya6iyv5v32fxr', //Consumer secret registered in server administration
'callbackUrl' => 'http://magento.loc/restconnect/test/callback', //Url of callback action below
);
 
$oAuthClient = Mage::getModel('inchoo_restconnect/oauth_client');
$oAuthClient->reset();
 
$oAuthClient->init($params);
$oAuthClient->authenticate();
 
return;
}
 
public function callbackAction() {
 
$oAuthClient = Mage::getModel('inchoo_restconnect/oauth_client');
$params = $oAuthClient->getConfigFromSession();
$oAuthClient->init($params);
 
$state = $oAuthClient->authenticate();
 
if ($state == Inchoo_RestConnect_Model_OAuth_Client::OAUTH_STATE_ACCESS_TOKEN) {
$acessToken = $oAuthClient->getAuthorizedToken();
}
 
$restClient = $acessToken->getHttpClient($params);
// Set REST resource URL
$restClient->setUri('http://magento.loc/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;
}
 
}

If you use this source, please leave the credit at the top of the file. Thanks.

I hope this article helped to better understand oAuth and REST web services with Magento. 🙂

In case you’re going to need any other help with your Magento development, we’re here for you!