Error while using REST api in magento - api

I have set up magento locally in my system using XAMPP
I have created a file in root directory named dm.php with the contents
<?php
/**
* Example of products list retrieve using Customer account via Magento REST API. OAuth authorization is used
*/
$callbackUrl = "http://localhost/dm.php";
$temporaryCredentialsRequestUrl = "http://localhost/mage2/oauth/initiate?oauth_callback=" . urlencode($callbackUrl);
$adminAuthorizationUrl = 'http://localhost/mage2/oauth/authorize';
$accessTokenRequestUrl = 'http://localhost/mage2/oauth/token';
$apiUrl = 'http://localhost/mage2/api/rest';
$consumerKey = 'enhksf7u33p3snubewb6zcq0z9c63bvv';
$consumerSecret = 'p7e835cdcxofokeep749jgzz4l1e306p';
session_start();
if (!isset($_GET['oauth_token']) && isset($_SESSION['state']) && $_SESSION['state'] == 1) {
$_SESSION['state'] = 0;
}
try {
$authType = ($_SESSION['state'] == 2) ? OAUTH_AUTH_TYPE_AUTHORIZATION : OAUTH_AUTH_TYPE_URI;
$oauthClient = new OAuth($consumerKey, $consumerSecret, OAUTH_SIG_METHOD_HMACSHA1, $authType);
$oauthClient->enableDebug();
if (!isset($_GET['oauth_token']) && !$_SESSION['state']) {
$requestToken = $oauthClient->getRequestToken($temporaryCredentialsRequestUrl);
$_SESSION['secret'] = $requestToken['oauth_token_secret'];
$_SESSION['state'] = 1;
header('Location: ' . $adminAuthorizationUrl . '?oauth_token=' . $requestToken['oauth_token']);
exit;
} else if ($_SESSION['state'] == 1) {
$oauthClient->setToken($_GET['oauth_token'], $_SESSION['secret']);
$accessToken = $oauthClient->getAccessToken($accessTokenRequestUrl);
$_SESSION['state'] = 2;
$_SESSION['token'] = $accessToken['oauth_token'];
$_SESSION['secret'] = $accessToken['oauth_token_secret'];
header('Location: ' . $callbackUrl);
exit;
} else {
$oauthClient->setToken($_SESSION['token'], $_SESSION['secret']);
$resourceUrl = "$apiUrl/products";
$oauthClient->fetch($resourceUrl);
$productsList = json_decode($oauthClient->getLastResponse());
print_r($productsList);
}
} catch (OAuthException $e) {
print_r($e);
}
But this is giving me the following error
Fatal error: Class 'OAuth' not found in D:\Webserver\xampp\htdocs\dm.php on line 19
Can anybody shed some light on this
Thanks
Since oauth is not possible to install in xampp windows i changed the contents of my dm.php file to this.
<?php
$ch = curl_init('http://localhost/mage2/api/rest/customers');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$customers = curl_exec($ch);
echo $customers;
?>
Now i am getting an error like this
{"messages":{"error":[{"code":403,"message":"Access denied"}]}}
What am i doing wrong?

First of all
Go to magento admin panel System->Webservice->RESt Roles->Guest->Resources Access ->SET ALL
Similarly Go to System->Webservice->RESt Attribute->Guest->Resources Access ->SET ALL
Then Hit this url http://****/chanchal/magento/api/rest/products in web Browser and check what error it shows....
According to me it must show product in your website in xml format.
Please let me know..
EDIT:
I configured a localhost just now and got this output refer the Screenshot. Be sure there is product in your magento.
Similarly follow the above steps for admin,customer then create a Ouath consumer from admin panel , Install RESTClient For Mozilla Firefox And follow Here
These for steps are necessary for the setup..the link might help you..
Authentication Endpoints
1./oauth/initiate - this endpoint is used for retrieving the Request Token.
2./oauth/authorize - this endpoint is used for user authorization (Customer).
3./admin/oauth_authorize - this endpoint is used for user authorization (Admin).
4./oauth/token - this endpoint is used for retrieving the Access Token.
Let me know if you have any issues.
Best of luck

A bit of code modifications will easily solve this error 403 forbidden.
What magento engine does is that it uses the default guest user to provide access to the REST api methods. The guest user does not have much powers so it should be better to change this functionality of magento. There are 2 ways of doing this:
1) Quick and dirty fix: in the file /app/code/core/Mage/Api2/Model/Auth.php, change the value of: DEFAULT_USER_TYPE = 'guest' to DEFAULT_USER_TYPE = 'admin'. In the file /app/code/core/Mage/Api2/Model/Auth/Adapter.php, change this line from return (object) array('type' => Mage_Api2_Model_Auth::DEFAULT_USER_TYPE, 'id' => null); to this:
return (object) array('type' => Mage_Api2_Model_Auth::DEFAULT_USER_TYPE, 'id' => '1');
This way the authentication system will not be broken.
2) Proper and long run fix: Override the two functionalities using the magento overriding mechanism to have a better solution in accordance to magento standards. This way the core files will be intact.

We use this link to install oauth for php. Its good and easy to add extension for php.
install oauth php
I hope it helps to all and would solved 'OAuth' not found fatal error.

I had the same issue and was struggling for a week but just try insatlling new version of xammp or wamp with supports ouath.The better solution was ,I installed Ammps 1.9 and in php5.4 I resolved the extension of oauth but still make sure that you select the proper php for extension oauth is supported (php5.4)

For installing Oauth : http://www.magentocommerce.com/api/rest/authentication/oauth_authentication.html
Installing PHP Extension for Oauth :
1. Download php_oauth.dll file and add it under C:\xampp\php\ext\
2. add [PHP_OAUTH] extension=php_oauth.dll in php.ini

Related

PayPal - Payer is not identified

I'm currently working on a project who use Magento and PayPal. I have configured the PayPal settings with a sandbox which I use on multiple projects, when I choose to pay with PayPal on the sandbox mode, I can pay correctly but when I got redirected to the shop I got the error "Payer is not identified" and cannot proceed the order.
The shop is under a proxy who is configured in PayPal too. The email to pay is a one I use on other project too and I do not have problem.
Any hint or idea ? Proxy related ?
Finally find out it was on the Call of the API NVP, it was a conflict with the proxy where sometimes the answer of the call got an array of 4 (to send) and an array of 3 (to get).
In app\code\core\Mage\Paypal\Model\Api\Nvp.php line 973
I have changed
$response = preg_split('/^\r?$/m', $response, 2);
$response = trim($response[1]);
$response = $this->_deformatNVP($response);
to
$answer = preg_split('/^\r?$/m', $response, 4);
if($answer[3]) {
$response = preg_split('/^\r?$/m', $response, 4);
$response = trim($response[3]);
} else {
$response = preg_split('/^\r?$/m', $response, 3);
$response = trim($response[2]);
}
$response = $this->_deformatNVP($response);
Of course, I have overrided the Class to keep the core code clean.
Magento version: 1.9.2.4
Hope it can help someone.
I found this to be a problem with one of Magentos patches not being applied correctly
make sure your system has this file in place
/lib/Unserialize/Reader/Null.php
its part of this patch SUPEE-8788

Google login in PHP backend and JS frontend

Front end is 100% JS. User click on sign in button and an authResult['code'] is received and send via ajax to localhost/api/user/login which has the following content:
$code = $data['code'];
require_once 'Google/Client.php';
$client = new Google_Client();
$client->setClientId('xxxxxx');
$client->setClientSecret('xxxxx');
$client->setRedirectUri('http://localhost:8080');
$client->setScopes('email'); //Why do I need this? I already set scope in JS.
$client->authenticate($code); //It fails here. with no error. just 400 bad request.
$token = json_decode($client->getAccessToken());
$reqUrl = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=' .
$token->access_token;
$req = new Google_HttpRequest($reqUrl);
$tokenInfo = json_decode(
$client::getIo()->authenticatedRequest($req)->getResponseBody());
//Check errors.
//Save user personal info in database
//Set login sessions
Why do I need to set scopes if I already set them in javascript?
Why is it failing when authenticate function is called? Im getting no erros.
Why do I need a setRedirectUri() when it is on the backend?
You don't need to set scopes in this case.
(see answer 3, but also): Check your client ID matches the one used in the Javascript, and that the client secret is exactly as in the console (no trailing/leading spaces).
Changing your redirecturi to 'postmessage' - this is the string used when the code was generated via the Javascript process.
You can also try manually constructing the URL and calling it with curl to make sure everything is as you expect: https://developers.google.com/accounts/docs/OAuth2WebServer#handlingtheresponse

Not able to use Magento REST APIs using OAuth

I am using Magento version 1.7.0.2 and trying to use Magento Rest APIs using OAuth Integration.
I have installed OAuth and following is the snippet of code that i have put in root directory of magento and i am running it in web browser by typing http://x.x.x.x:5009/oauth_customer.php
$callbackUrl = "http://x.x.x.x:5009/oauth_customer.php";
$temporaryCredentialsRequestUrl = "http://x.x.x.x:5009/oauth/initiate?oauth_callback=" . urlencode($callbackUrl);
$adminAuthorizationUrl = 'http://x.x.x.x:5009/oauth/authorize';
$accessTokenRequestUrl = "http://x.x.x.x:5009/oauth/token";
$apiUrl = "http://x.x.x.x:5009/api/rest";
$consumerKey = 'yourconsumerkey';
$consumerSecret = 'yourconsumersecret';
session_start();
if (!isset($_GET['oauth_token']) && isset($_SESSION['state']) && $_SESSION['state'] == 1) {
$_SESSION['state'] = 0;
}
try {
$authType = ($_SESSION['state'] == 2) ? OAUTH_AUTH_TYPE_AUTHORIZATION : OAUTH_AUTH_TYPE_URI;
$oauthClient = new OAuth($consumerKey, $consumerSecret, OAUTH_SIG_METHOD_HMACSHA1, $authType);
$oauthClient->enableDebug();
if (!isset($_GET['oauth_token']) && !$_SESSION['state']) {
$requestToken = $oauthClient->getRequestToken($temporaryCredentialsRequestUrl);
$_SESSION['secret'] = $requestToken['oauth_token_secret'];
$_SESSION['state'] = 1;
header('Location: ' . $adminAuthorizationUrl . '?oauth_token=' . $requestToken['oauth_token']);
exit;
} else if ($_SESSION['state'] == 1) {
$oauthClient->setToken($_GET['oauth_token'], $_SESSION['secret']);
$accessToken = $oauthClient->getAccessToken($accessTokenRequestUrl);
$_SESSION['state'] = 2;
$_SESSION['token'] = $accessToken['oauth_token'];
$_SESSION['secret'] = $accessToken['oauth_token_secret'];
header('Location: ' . $callbackUrl);
exit;
} else {
$oauthClient->setToken($_SESSION['token'], $_SESSION['secret']);
$resourceUrl = "$apiUrl/products";
$oauthClient->fetch($resourceUrl);
$productsList = json_decode($oauthClient->getLastResponse());
print_r($productsList);
}
} catch (OAuthException $e) {
print_r($e);
}
http://x.x.x.x:5009 is ip address followed 5009 where 5009 is port number specified.
When we run this in the browser, i always get the following error -
Invalid auth/bad request (got a 401, expected HTTP/1.1 20X or a redirect)
oauth_problem=signature_invalid&debug_sbs=Bya6oE4ujTEEFLVL6Mm04PqTA4g=
I am not able to get this work.
Note - I have generated consumer key and secret key. Not sure of how created user credentials with customer access to REST API Resources fit into the above script.
Also i want to know if we can use magento apis on any non magento site with oAuth integration programatically without the user having to grant access to application each time to generate request token.
You have to generate oauth token first. Follow this http://www.aschroder.com/2012/04/introduction-to-the-magento-rest-apis-with-oauth-in-version-1-7/ then test http://www.magentocommerce.com/api/rest/testing_rest_resources.html
If you dont want authentication you can use curl to get desired data. http://snipplr.com/view/44760/
In url pass valid magento resource url like www.yourwebsite.com/api/rest/products

Codeigniter API error returning

Hi has anyone any experience using Phil Sturgeons RESTFUL libraries for codeigniter. I've decided to create a web service for our database in order to supply access to the database from multiple applications. The website is currently developed in Codeigniter therefore it was a simple solution to use the rest API libraries.
The problem I have is that I am trying to return specific errors in the event of a problem.
At the moment I am purposely returning an error like so:
require(APPPATH . 'libraries/REST_Controller.php');
class Settings_api extends REST_Controller {
function settings_get()
{
$this->response(NULL, 404);
}
}
If I access the url directly then I am just receiving a blank page, I can return a message if I replace the 'NULL' with a message but there is nothing to say its a 404 error whereas If I call the page via php using the following
$user = json_decode(file_get_contents('http://www.example.co.uk/api/settings_api/settings/'));
echo $user;
then it shows the following line
Message: file_get_contents(http://www.example.co.uk/api/settings_api/settings/) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.1 404
In both instances I would like to return a 404 error along with a message I provide. Is this possible and if so could you point me in the right direction.
Thanks
The error message being generated by PHP, as far as I know, there's nothing you can do about this (other than using the # operator, which I do NOT recommend). So, your only option is to manually check file_get_content()'s return value:
$response = file_get_contents('http://...');
if ($response === false) {
// return whatever you feel is appropriate
} else {
$user = json_decode($response);
echo $user;
}
EDIT
Found this answer here on Stackoverflow which is what you are looking for.

Symfony REST API authentication without sfGuardPlugin

I'm trying to find information on securing a HTTP REST API in a Symfony project, but all I can find is information about using sfGuardPlugin. From what I can see, this plugin isn't very useful for web services. It tries to have user profile models (which aren't always that simple) and have "sign in" and "sign out" pages, which obviously are pointless for a stateless REST API. It does a lot more than I'll ever have need for and I what to keep it simple.
I want to know where to implement my own authorisation method (loosely based on Amazon S3's approach). I know how I want the authorisation method to actually work, I just don't know where I can put code in my Symfony app so that it runs before every request is processed, and lets approved requests continue but unsuccessful requests return a 403.
Any ideas? I can't imagine this is hard, I just don't know where to start looking.
There is a plugin for RESTful authentication -> http://www.symfony-project.org/plugins/sfRestfulAuthenticationPlugin
Not used it though ....
How where you planning to authenticate users ?
The jobeet tutorial uses tokens ... http://www.symfony-project.org/jobeet/1_4/Doctrine/en/15
I ended up finding what I was looking for by digging into the code for sfHttpAuthPlugin. What I was looking for was a "Filter". Some details and an example is described in the Askeet sample project.
Stick a HTTP basicAuth script in your <appname>_dev.php (Symfony 1.4 =<) between the project configuration "require" and the configuration instance creation.
Test it on your dev. If it works, put the code in your index.php (the live equivalent of <appname>_dev.php) and push it live.
Quick and dirty but it works. You may want to protect that username/password in the script though.
e.g.
$realm = 'Restricted area';
//user => password
$users = array('username' => 'password');
if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Digest realm="'.$realm.
'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');
die('Text to send if user hits Cancel button');
}
// || !isset($users[$data['username']]
// analyze the PHP_AUTH_DIGEST variable
if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) || !isset($users[$data['username']])) {
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Digest realm="'.$realm.
'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');
die('Wrong Credentials!');
}
// generate the valid response
$A1 = md5($data['username'] . ':' . $realm . ':' . $users[$data['username']]);
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
$valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);
if ($data['response'] != $valid_response) {
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Digest realm="'.$realm.
'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');
die('Wrong Credentials!');
}
// function to parse the http auth header
function http_digest_parse($txt)
{
// protect against missing data
$needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
$data = array();
$keys = implode('|', array_keys($needed_parts));
preg_match_all('#(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))#', $txt, $matches, PREG_SET_ORDER);
foreach ($matches as $m) {
$data[$m[1]] = $m[3] ? $m[3] : $m[4];
unset($needed_parts[$m[1]]);
}
return $needed_parts ? false : $data;
}
// ****************************************************************************
// ok, valid username & password.. continue...