Getting error while calling magento 1.9.2 rest api - api

I am using Magento 1.9.2 vesrion for. Using below code for calling rest api.
public function indexAction() {
//Basic parameters that need to be provided for oAuth authentication
//on Magento
$params = array(
'siteUrl' => 'http://127.0.0.1:8080/magentodemo/',
'requestTokenUrl' => 'http://127.0.0.1:8080/magentodemo/oauth/initiate',
'accessTokenUrl' => 'http://127.0.0.1:8080/magentodemo/oauth/token',
'authorizeUrl' => 'http://127.0.0.1:8080/magentodemo/admin/oauth_authorize',//This URL is used only if we authenticate as Admin user type
'consumerKey' => 'c359b57d0d069a336db94fa4aabd61ce',//Consumer key registered in server administration
'consumerSecret' => '2ef029c871b7c013619cc15445a83c25',//Consumer secret registered in server administration
'callbackUrl' => 'http://127.0.0.1:8080/magentodemo/restconnect/index/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://127.0.0.1:8080/magentodemo/',
'requestTokenUrl' => 'http://127.0.0.1:8080/magentodemo/oauth/initiate',
'accessTokenUrl' => 'http://127.0.0.1:8080/magentodemo/oauth/token',
'consumerKey' => 'c359b57d0d069a336db94fa4aabd61ce',
'consumerSecret' => '2ef029c871b7c013619cc15445a83c25'
);
// 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://127.0.0.1:8080/magentodemo/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;
}
Getting below error every time
a:5:{i:0;s:83:"Could not retrieve a valid Token response from Token URL:
oauth_problem=nonce_used";i:1;s:1453:"#0 D:\xampp\htdocs\magentodemo\lib\Zend\Oauth\Http.php(190): Zend_Oauth_Http->_assessRequestAttempt(Object(Zend_Http_Response))
#1 D:\xampp\htdocs\magentodemo\lib\Zend\Oauth\Http.php(191): Zend_Oauth_Http->startRequestCycle(Array)
#2 D:\xampp\htdocs\magentodemo\lib\Zend\Oauth\Http.php(191): Zend_Oauth_Http->startRequestCycle(Array)
#3 D:\xampp\htdocs\magentodemo\lib\Zend\Oauth\Http\RequestToken.php(51): Zend_Oauth_Http->startRequestCycle(Array)
#4 D:\xampp\htdocs\magentodemo\lib\Zend\Oauth\Consumer.php(115): Zend_Oauth_Http_RequestToken->execute()
#5 D:\xampp\htdocs\magentodemo\app\code\local\Test\RestConnect\controllers\IndexController.php(52): Zend_Oauth_Consumer->getRequestToken()
#6 D:\xampp\htdocs\magentodemo\app\code\core\Mage\Core\Controller\Varien\Action.php(418): Test_RestConnect_IndexController->indexAction()
#7 D:\xampp\htdocs\magentodemo\app\code\core\Mage\Core\Controller\Varien\Router\Standard.php(254): Mage_Core_Controller_Varien_Action->dispatch('index')
#8 D:\xampp\htdocs\magentodemo\app\code\core\Mage\Core\Controller\Varien\Front.php(172): Mage_Core_Controller_Varien_Router_Standard->match(Object(Mage_Core_Controller_Request_Http))
#9 D:\xampp\htdocs\magentodemo\app\code\core\Mage\Core\Model\App.php(365): Mage_Core_Controller_Varien_Front->dispatch()
#10 D:\xampp\htdocs\magentodemo\app\Mage.php(684): Mage_Core_Model_App->run(Array)
#11 D:\xampp\htdocs\magentodemo\index.php(83): Mage::run('', 'store')
#12 {main}";s:3:"url";s:31:"/magentodemo/restconnect/index/";s:11:"script_name";s:22:"/magentodemo/index.php";s:4:"skin";s:7:"default";}
I have already created, REST Role for Admin and Assigned to one of the admin user, REST Attribute for Admin, REST Consumers is also created.
Any help will be appreciated.

There was a small fix for above issue. But it takes my 1 day to fix it. In my system apache was running on 8080 port. There is issue in magento oauth to read port while URI validation.
I have stopped other service (IIS or Skype), in my case it was IIS. and port apache on 80. This is the default port.
Hope this will help to someone!!!

Related

vue-cli frontend not setting CSRF cookie from Sanctum

I am developing a new frontend using Vue to access my existing Laravel 7 app, which uses Sanctum for authentication.
The frontend sits on app.example.com, with the backend being moved to api.example.com. The CORS middleware and Sanctum are properly configured to allow app.example.com, and so far so good.
The GET to /sanctum/csrf-cookie looks fine, however, it doesn't seem to be actually setting the cookies, causing the subsequent request to the API to return a 419.
const config = { withCredentials: true };
const api = process.env.NODE_ENV === 'production' ? 'https://api.example.com' : 'http://localhost:9000';
axios.get(api + '/sanctum/csrf-cookie', config)
.then(() => axios.post(api + '/login', data, config))
.then(response => response.json())
.then(response => { console.log('json', response); });
Console log:
Response headers from /sanctum/csrf-cookie:
No cookies are listed in devtools:
UPDATE 1: Didn't notice this earlier; the warning icons next to each Set-Cookie in the response headers display "This set-cookie's Domain attribute was invalid with respect to the current host url."
Short answer: Ports should not be specified in cookie domain attributes.
Long answer: Laravel Sanctum uses the VerifyCsrfToken middleware to both send and verify the CSRF token, which uses session config values when adding the cookie to the response:
protected function addCookieToResponse($request, $response)
{
$config = config('session');
if ($response instanceof Responsable) {
$response = $response->toResponse($request);
}
$response->headers->setCookie(
new Cookie(
'XSRF-TOKEN', $request->session()->token(), $this->availableAt(60 * $config['lifetime']),
$config['path'], $config['domain'], $config['secure'], false, false, $config['same_site'] ?? null
)
);
return $response;
}
In config/session.php:
'domain' => env('SESSION_DOMAIN', null),
In .env:
SESSION_DOMAIN=localhost:8080
Cookies on the same host ARE NOT distinguishable by ports. Because I had specified the port in the cookie domain, the browser had flagged the cookie as having an invalid domain. Removing the port did the trick.
For me to solve the problem I changed my vue cli host which was 127.0.0.1:8080 to localhost:8080 in browser,and within axios the base url is now http://localhost:7000 which is for laravel api.
after that I then set SESSION_DOMAIN=localhost in .env laravel

mautic - I want to add contact in mautic via api

I want to add contact in mautic via an API. Below I have the code, but it's not adding the contact in mautic.
I have installed mautic in localhost. Studied the API form in the mautic documentation and tried to do it for at least 2 days, but I am not getting any results on it.
<?php
// Bootup the Composer autoloader
include __DIR__ . '/vendor/autoload.php';
use Mautic\Auth\ApiAuth;
session_start();
$publicKey = '';
$secretKey = '';
$callback = '';
// ApiAuth->newAuth() will accept an array of Auth settings
$settings = array(
'baseUrl' => 'http://localhost/mautic', // Base URL of the Mautic instance
'version' => 'OAuth2', // Version of the OAuth can be OAuth2 or OAuth1a. OAuth2 is the default value.
'clientKey' => '1_1w6nrty8k9og0kow48w8w4kww8wco0wcgswoow80ogkoo0gsks', // Client/Consumer key from Mautic
'clientSecret' => 'id6dow060fswcswgsgswgo4c88cw0kck4k4cc0wkg4gows08c', // Client/Consumer secret key from Mautic
'callback' => 'http://localhost/mtest/process.php' // Redirect URI/Callback URI for this script
);
/*
// If you already have the access token, et al, pass them in as well to prevent the need for reauthorization
$settings['accessToken'] = $accessToken;
$settings['accessTokenSecret'] = $accessTokenSecret; //for OAuth1.0a
$settings['accessTokenExpires'] = $accessTokenExpires; //UNIX timestamp
$settings['refreshToken'] = $refreshToken;
*/
// Initiate the auth object
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
/*
if( $auth->getAccessTokenData() != null ) {
$accessTokenData = $auth->getAccessTokenData();
$settings['accessToken'] = $accessTokenData['access_token'];
$settings['accessTokenSecret'] = 'id6dow060fswcswgsgswgo4c88cw0kck4k4cc0wkg4gows08c'; //for OAuth1.0a
$settings['accessTokenExpires'] = $accessTokenData['expires']; //UNIX timestamp
$settings['refreshToken'] = $accessTokenData['refresh_token'];
}*/
// Initiate process for obtaining an access token; this will redirect the user to the $authorizationUrl and/or
// set the access_tokens when the user is redirected back after granting authorization
// If the access token is expired, and a refresh token is set above, then a new access token will be requested
try {
if ($auth->validateAccessToken()) {
// Obtain the access token returned; call accessTokenUpdated() to catch if the token was updated via a
// refresh token
// $accessTokenData will have the following keys:
// For OAuth1.0a: access_token, access_token_secret, expires
// For OAuth2: access_token, expires, token_type, refresh_token
if ($auth->accessTokenUpdated()) {
$accessTokenData = $auth->getAccessTokenData();
echo "<pre>";
print_r($accessTokenData);
echo "</pre>";
//store access token data however you want
}
}
} catch (Exception $e) {
// Do Error handling
}
use Mautic\MauticApi;
//use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "http://localhost/mautic/api";
$api = new MauticApi();
$contactApi = $api->newApi("contacts", $auth, $apiUrl);
$data = array(
'firstname' => 'Jim',
'lastname' => 'Contact',
'email' => 'jim#his-site.com',
'ipAddress' => $_SERVER['REMOTE_ADDR']
);
$contact = $contactApi->create($data);
echo "<br/>contact created";
Any help will be appreciated.
use Curl\Curl;
$curl = new Curl();
$un = 'mayank';
$pw = 'mayank';
$hash = base64_encode($un.':'.$pw);
$curl->setHeader('Authorization','Basic '.$hash);
$res = $curl->post(
'http://mautic.local/api/contacts/new',
[
'firstname'=>'fn',
'lastname'=>'ln',
'email'=>'t1#test.com'
]
);
var_dump($res);
This is something very simple i tried and it worked for me, please try cleaning cache and enable logging, unless you provide us some error it's hard to point you in right direction. Please check for logs in app/logs directory as well as in /var/logs/apache2 directory.
In my experience sometimes after activating the API in the settings the API only starts working after clearing the cache.
Make sure you have activated the API in the settings
Clear the cache:
cd /path/to/mautic
rm -rf app/cache/*
Then try again
If this didn't work, try to use the BasicAuth example (You have to enable this I the settings again and add a new User to set the credentials)
I suspect that the OAuth flow might be disturbed by the local settings / SSL configuration.
these steps may be useful:
make sure API is enabled(yes I know it's might be obvious but still);
check the logs;
check the response body;
try to send it as simple json via Postman
it may be one of the following problems:
Cache;
You are not sending the key:value; of the required custom field;
you are mistaken with authentication;
Good luck :)

Not able to redirect to client side with token from server(express) side route

I am using 'googleapis' npm package to do token based google authentication.
I am redirected to '/api/auth/success/google' route inside express after google provided authentication and redirects us to the uri stated in google app credentials.
The problem I am facing is that ,I have retrieved the tokens on server side,but I am unable to send those tokens to client side for them to be saved in cookies.
The problem I am facing is because,'/api/auth/success/google' is redirected from google side and not an ajax call from client side.So if I send the tokens back in res,where will it redirect.Also please suggest a way to redirect from server side to client side,along with access_token.
server side code.
//Route reached after google successful login/authentication
app.get('/api/auth/success/google',function(req,res){
console.log("inside redirect");
var code = req.query.code;
oauth2Client.getToken(code, function(err, tokens) {
// Now tokens contains an access_token and an optional refresh_token. Save them.
if(!err) {
oauth2Client.setCredentials(tokens);
}
res.sendFile('./index.html');
});
})
Client side call
//Google login requested from this function
googleLogin(){
event.preventDefault();
$.ajax({
type : 'POST',
url : baseURL + 'api/authenticate/google',
success: (function(data) {
if (data.redirect) {
document.location.href = data.redirect;
}
}).bind(this)
});
}
//Route handling request of google access
app.post('/api/authenticate/google',function(req,res){
// generate a url that asks permissions for Google+ and Google Calendar scopes
var scopes = [
googlecredentials.SCOPE[0],
googlecredentials.SCOPE[1]
];
var url = oauth2Client.generateAuthUrl({
access_type: 'offline', // 'online' (default) or 'offline' (gets refresh_token)
scope: scopes // If you only need one scope you can pass it as string
});
res.send({ redirect: url });
})
//Google App Credentials
var OAuth2 = google.auth.OAuth2;
var oauth2Client = new OAuth2(googlecredentials.CLIENT_ID, googlecredentials.CLIENT_SECRET, googlecredentials.REDIRECT_URL);
googlecredentials.CLIENT_ID - 858093863410-j9ma1i7lgapupip1ckegc61plrlledtq.apps.googleusercontent.com
REDIRECT_URL - http://localhost:3000/api/auth/success/google where localhost:3000 runs server side
If you send the redirect URL back in the res, the client-side should be able to check for the presence of the redirect URL in the response, and if it exists, push your user to that URL.

Paypal REST API invalid credentials

I use the REST api in my nodejs application.
All is working good with sandbox but when i update with live credentials i get:
{ [Error: Response Status : 401]
response:
{ error: 'invalid_client',
error_description: 'The client credentials are invalid',
httpStatusCode: 401 },
httpStatusCode: 401 }
I updated my account to buisness but still not working, i use the live endpoint and Live credentials.
What should i do in order to make this work?
I had the same issue using PayPalSDK/rest-sdk-nodejs and solved passing with the configuration parameters (host, client_id, client_secret, ...) also the parameter 'mode' set to 'live'. Otherwise the default mode used by the library is 'sandbox' and hence the impossibility to use the live credentials.
As matteo said, if you switch from dev to live environment, only updateing the client id and secret isn't enough. You need to set the ApiContext-Mode to "live".
PayPals PHP REST-API-SDK comes with some great samples. Take a look at the bootstrap.php in /vendor/paypal/rest-api-sdk-php/sample/ in line 84. There are some configurations happening, after getting the api context.
<?php
$apiContext = new ApiContext(
new OAuthTokenCredential(
$clientId,
$clientSecret
)
);
// Comment this line out and uncomment the PP_CONFIG_PATH
// 'define' block if you want to use static file
// based configuration
$apiContext->setConfig(
array(
'mode' => 'sandbox',
'log.LogEnabled' => true,
'log.FileName' => '../PayPal.log',
'log.LogLevel' => 'DEBUG', // PLEASE USE `INFO` LEVEL FOR LOGGING IN LIVE ENVIRONMENTS
'cache.enabled' => true,
// 'http.CURLOPT_CONNECTTIMEOUT' => 30
// 'http.headers.PayPal-Partner-Attribution-Id' => '123123123'
//'log.AdapterFactory' => '\PayPal\Log\DefaultLogFactory' // Factory class implementing \PayPal\Log\PayPalLogFactory
)
);

Backbone.js and user authentication

I have been wondering for quite a while how I would go about authenticating users using Backbone because I have been reading a few articles about it and a lot of them are talking about tokens and keys.. But I just want to be able to sign in a user and register a user like you would normally.
I was thinking that on the web app start up there would be a request to the route '/me' and then the server gives the user back appropriate information if he/she is logged in.
Like if the route came back with {loggedIn: false} the backbone router would send the user to the login/register pages only. But if it came back with a users profile information then it would obviously mean he had a session.
Is this an okay way of going back user authentication when using Backbone?
Short answer: wire up $.ajax to respond to 401 (Unauthorized) status codes.
Long answer: We're consuming a RESTful api from a single page website. when the server detects an unauthorized request, it just returns a 401. The client will redirect to /login?#requested/resource.
/login will prompt for authorization (redirect to google's oath server in our case) then add an authorization cookie and redirect to the originally requested #requested/resource
we're also sending the auth cookie on every $.ajax request.
Hopefully this is helpful.
define(
[
'jquery',
'jquery.cookie'
],
function ($) {
var redirectToLogin = function () {
var locationhref = "/login";
if (location.hash && location.hash.length > 0) {
locationhref += "?hash=" + location.hash.substring(1);
}
location.href = locationhref;
};
var $doc = $(document);
$doc.ajaxSend(function (event, xhr) {
var authToken = $.cookie('access_token');
if (authToken) {
xhr.setRequestHeader("Authorization", "Bearer " + authToken);
}
});
$doc.ajaxError(function (event, xhr) {
if (xhr.status == 401)
redirectToLogin();
});
});