This question already has answers here:
Magento Rest API Oauth URL Returning 404
(5 answers)
Closed 8 years ago.
When following the documentation from here
http://www.magentocommerce.com/api/rest/introduction.html
The sample code below 404s when it tries to make the calls to the urls /oauth/initiate and
/admin/oauth_authorize.
/api/rest works fine, as I have the current rule in .htaccess
RewriteRule ^api/rest api.php?type=rest [QSA,L]
Is there other rules I am missing? It was my understanding the magento REST api should work out the box. Or could the issue be unrelated to url rewrites?
I have created the appropriate REST Roles and Attributes and placed the consumer key/secret inside the sample code also but no dice.
Just to clarify, a guest role works fine when hitting api/rest using a rest client or browser. However trying to set up authentication with the below sample code is causing me issues for the above reasons.
<?php
/**
* Example of simple product POST using Admin account via Magento REST API. OAuth authorization is used
*/
$callbackUrl = "http://yourhost/oauth_admin.php";
$temporaryCredentialsRequestUrl = "http://magentohost/oauth/initiate?oauth_callback=" . urlencode($callbackUrl);
$adminAuthorizationUrl = 'http://magentohost/admin/oauth_authorize';
$accessTokenRequestUrl = 'http://magentohost/oauth/token';
$apiUrl = 'http://magentohost/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";
$productData = json_encode(array(
'type_id' => 'simple',
'attribute_set_id' => 4,
'sku' => 'simple' . uniqid(),
'weight' => 1,
'status' => 1,
'visibility' => 4,
'name' => 'Simple Product',
'description' => 'Simple Description',
'short_description' => 'Simple Short Description',
'price' => 99.95,
'tax_class_id' => 0,
));
$headers = array('Content-Type' => 'application/json');
$oauthClient->fetch($resourceUrl, $productData, OAUTH_HTTP_METHOD_POST, $headers);
print_r($oauthClient->getLastResponseInfo());
}
} catch (OAuthException $e) {
print_r($e);
} ?>
Does this part $callbackUrl = "http://yourhost/oauth_admin.php"; works? If if it is not working, fix this. Remember to replace value http://yourhost/oauth_admin.php with right value and try in your browser first.
Make sure that both yourhost and magentohost local or both remote server. For example if your magentohost is remote server and yourhost is local, redirection will fail and you will get 404 error.
Related
I'm getting this error (I'm using PHP 7.0 and Google PHP API 2.9.1, and I'm using OAuth credentials for Web application):
Uncaught Error: Class 'Google_Service_Gmail_Resource_Users' not found in /google-api-2.9.1/vendor/google/apiclient-services/src/Google/Service/Gmail.php:106
Stack trace:
#0 /public_html/oauth2callback.php(20): Google_Service_Gmail->__construct(Object(Google\Client))
#1 {main} thrown in /public_html/googe-api-2.9.1/vendor/google/apiclient-services/src/Google/Service/Gmail.php on line 106
And here is what Im trying to do:
My index.php:
<?php
include_once __DIR__ . '/google-api-2.9.1/vendor/autoload.php';
$client = new Google_Client();
$client->setAuthConfig(__DIR__ . 'credenciales.json');
$client->addScope(Google_Service_Gmail::GMAIL_READONLY);
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$client->setAccessToken($_SESSION['access_token']);
$gmail = new Google_Service_Gmail($client);
$user = 'me';
$list = $gmail->users_messages->listUsersMessages($user, [ 'q' => ['from:someEmail#gmail.com in:inbox'], ]);
$messageList = $list->getMessages();
$inboxMessage = [];
foreach($messageList as $mlist){
$optParamsGet2['format'] = 'full';
$single_message = $gmail->users_messages->get('me',$mlist->id, $optParamsGet2);
$message_id = $mlist->id;
$headers = $single_message->getPayload()->getHeaders();
$snippet = $single_message->getSnippet();
foreach($headers as $single) {
if ($single->getName() == 'Subject') {
$message_subject = $single->getValue();
}
else if ($single->getName() == 'Date') {
$message_date = $single->getValue();
$message_date = date('M jS Y h:i A', strtotime($message_date));
}
else if ($single->getName() == 'From') {
$message_sender = $single->getValue();
$message_sender = str_replace('"', '', $message_sender);
}
}
$inboxMessage[] = [
'messageId' => $message_id,
'messageSnippet' => $snippet,
'messageSubject' => $message_subject,
'messageDate' => $message_date,
'messageSender' => $message_sender
];
echo json_encode($inboxMessage);
}
} else {
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
My oauth2callback.php file:
<?php
require_once __DIR__ . '/google-api-2.9.1/vendor/autoload.php';
$client = new Google_Client();
$client->setAuthConfig(__DIR__ . 'credenciales.json');
$client->setRedirectUri('https://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
$client->addScope(Google_Service_Gmail::GMAIL_READONLY);
if (! isset($_GET['code'])) {
$auth_url = $client->createAuthUrl();
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$gmail = new Google_Service_Gmail($client);
$user = 'me';
$list = $gmail->users_messages->listUsersMessages($user, [ 'q' => ['from:someEmail#gmail.com in:inbox'], ]);
$messageList = $list->getMessages();
$inboxMessage = [];
foreach($messageList as $mlist){
$optParamsGet2['format'] = 'full';
$single_message = $gmail->users_messages->get('me',$mlist->id, $optParamsGet2);
$message_id = $mlist->id;
$headers = $single_message->getPayload()->getHeaders();
$snippet = $single_message->getSnippet();
foreach($headers as $single) {
if ($single->getName() == 'Subject') {
$message_subject = $single->getValue();
}
else if ($single->getName() == 'Date') {
$message_date = $single->getValue();
$message_date = date('M jS Y h:i A', strtotime($message_date));
}
else if ($single->getName() == 'From') {
$message_sender = $single->getValue();
$message_sender = str_replace('"', '', $message_sender);
}
}
$inboxMessage[] = [
'messageId' => $message_id,
'messageSnippet' => $snippet,
'messageSubject' => $message_subject,
'messageDate' => $message_date,
'messageSender' => $message_sender
];
echo json_encode($inboxMessage);
}
}
When I accept the app, google takes me to:
https://mywebsite.com/oauth2callback.php?code=4/8521e-kahsd875CLzcbtvppohs584ehtptRa6nXZpjhbFTDGFQjN9jgvQj_7be2E2j654ytv&scope=https://www.googleapis.com/auth/gmail.readonly
So, I go get pass the authorization screen from Google, I accept my app, and then a blank screen. The error shown comes from the error log file.
Why I get that Class 'Google_Service_Gmail_Resource_Users' is not found when I do call the autoload file?
So I see a few problems with your current setup. The one relating to your problem is that you aren't using Composer. It's small and simple and easy to use, and handles all the autoloading stuff for you. No worries about missing directories or unzipping errors. The download version of the Google API client already includes a pre-built Composer vendor folder, so you aren't saving any disk space or code complexity by skipping it.
Second is your directory structure; the way your server is set up, it's trivial for someone to access https://mywebsite.example.com/credenciales.json and get your private data.
So here's what I recommend:
In your document root (/var/www/html/home_dir) create a public folder and copy index.php and oauth2callback.php to that folder.
Update your server configuration to point to /var/www/html/home_dir/public as your document root
Change into /var/www/html/home_dir and run composer require google/apiclient (install Composer if you haven't already)
Edit your PHP files as needed, adjusting the path to credentiales.json and changing your require directives to point to /var/www/html/home_dir/vendor/autoload.php.
I have this PHP code.
<?php
require 'vendor/autoload.php';
$youtube_api_key = 'MY_KEY';
$playlist_id = 'PL3BE743993147F061';
$client = new \Google_Client();
$client->setDeveloperKey($youtube_api_key);
$youtube = new \Google_Service_YouTube($client);
try {
$playlistResponse = $youtube->playlists->listPlaylists('snippet', array(
'id' => $playlist_id
));
echo '<pre>'.print_r($playlistResponse, true).'</pre>';
} catch (\Google_Service_Exception $e) {
$gse_errors = $e->getErrors();
echo '<h1>error!</h1>';
echo '<pre>'.print_r($gse_errors, true).'</pre>';
}
If I did not enable Key restriction, this code works fine. But if I enable Key restriction it returns...
The request did not specify any referer. Please ensure that the client
is sending referer or use the API Console to remove the referer
restrictions.
How to enable Key restriction and make it work?
My 2nd test is...
<?php
require 'vendor/autoload.php';
session_start();
$youtube_api_key = 'MY_KEY';
$oauth_client_id = 'MY_CLIENT_ID';
$oauth_client_secret = 'MY_CLIENT_SECRET';
$playlist_id = 'PL3BE743993147F061';
//$client = new \Google_Client();
//$client->setDeveloperKey($youtube_api_key);
$client = new Google_Client();
$client->setClientId($oauth_client_id);
$client->setClientSecret($oauth_client_secret);
$client->setScopes('https://www.googleapis.com/auth/youtube');
$redirect = filter_var('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'], FILTER_SANITIZE_URL);
$client->setRedirectUri($redirect);
$youtube = new \Google_Service_YouTube($client);
$tokenSessionKey = 'token-' . $client->prepareScopes();
if (isset($_GET['code'])) {
if (strval($_SESSION['state']) !== strval($_GET['state'])) {
die('The session state did not match.');
}
$client->authenticate($_GET['code']);
$_SESSION[$tokenSessionKey] = $client->getAccessToken();
header('Location: ' . $redirect);
}
if (isset($_SESSION[$tokenSessionKey])) {
$client->setAccessToken($_SESSION[$tokenSessionKey]);
}
try {
if ($client->getAccessToken()) {
$playlistResponse = $youtube->playlists->listPlaylists('snippet', array(
'id' => $playlist_id
));
echo '<pre>'.print_r($playlistResponse, true).'</pre>';
} else {
// If the user hasn't authorized the app, initiate the OAuth flow
$state = mt_rand();
$client->setState($state);
$_SESSION['state'] = $state;
$authUrl = $client->createAuthUrl();
$htmlBody = <<<END
<h3>Authorization Required</h3>
<p>You need to authorize access before proceeding.<p>
END;
echo $htmlBody;
}
} catch (\Google_Service_Exception $e) {
$gse_errors = $e->getErrors();
echo '<h1>error!</h1>';
echo '<pre>'.print_r($gse_errors, true).'</pre>';
}
This code works fine with Key restriction but it required ALL users to authenticate using oAuth just to view the playlist and tracks info which is not good for any visitors at all.
The same question. How to enable Key restriction and make it work? (Without require any guest/user/visitor action.)
referrer:
https://developers.google.com/youtube/v3/code_samples/php#set_and_retrieve_localized_playlist_metadata
https://developers.google.com/youtube/v3/docs/
This worked for me
$referrer = 'my.domain';
$api_key = 'apikey';
$client = new Google_Client();
$client->setDeveloperKey($api_key);
$headers = array('Referer' => $referrer);
$guzzleClient = new \GuzzleHttp\Client(array( 'curl' => array( CURLOPT_SSL_VERIFYPEER => false, ), 'headers' => $headers ));
$client->setHttpClient($guzzleClient);
UPDATE ( to describe how I got to the code from above ):
I was receiving the same error response from the api request "The request did not specify any referrer". As the environment was local I've installed Charles Web Proxy ( as described in the repository instructions https://github.com/google/google-api-php-client/blob/master/README.md ) and have checked the request headers - then I've noticed that the referrer header was missing.
Then I looked for a way to pass that header to the request and noticed that the Guzzle HTTP Client Class had an option for that.
I'm not sure if that's the right way or if it's just a hack but it worked for me and hoped to be helpful for someone.
I'm attempting to connect to my magento api from an external server but i'm having an issue with OAuth.
I've created a consumer in the backend, assigned what it can access, authorized the consumer through oauth using terminal and it gave me my token and token secret.
My PHP is as follows;
<?php
$hostUrl = 'redacted';
$callbackUrl = $hostUrl."oauth_customer.php";
$temporaryCredentialsRequestUrl = $hostUrl."oauth/initiate?oauth_callback=".urlencode($callbackUrl);
$adminAuthorizationUrl = $hostUrl."oauth/authorize";
$accessTokenRequestUrl = $hostUrl."oauth/token";
$apiUrl = $hostUrl."api/rest";
$consumerKey = 'redacted';
$consumerSecret = 'redacted';
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, array(), 'GET', array('Content-Type' => 'application/json'));
$productsList = json_decode($oauthClient->getLastResponse());
print_r($productsList);
}
} catch (OAuthException $e) {
print_r($e->getMessage());
echo "<br/>";
print_r($e->lastResponse);
}
?>
When I run this php file it redirects me to the magento site and says;
AUTHORIZE APPLICATION
consumer_name requests access to your account
After authorization application will have access to you account.
Authorize | Reject
When I click "Authorize" it redirects me to a 404 within magento. If I return to the php file it will redirect me to that same "authorize application" page over and over again.
I already have the token and such so I assume that it should already be authorized.
I'm attempting to access the name of products as well as their inventory quantity so I can't simply use guest access. Any help would be greatly appreciated.
Your callback URL should not be on the remote host, it should be on your application's host.
Remove $callbackUrl row and exchange with this code:
$callbackUrl = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
I have added a PHP/JavaScript app as a Facebook page tab, and I'm hosting it on Heroku. However it's not receiving the signed_request. It comes through just fine when I host the tab on my own server, just not on Heroku.
Here is the code:
require_once('sdk/src/facebook.php');
$facebook = new Facebook(array(
'appId' => AppInfo::appID(),
'secret' => AppInfo::appSecret(),
'sharedSession' => true,
'trustForwarded' => true,
'cookie' => true
));
$signed_request = $facebook->getSignedRequest();
$liked = $signed_request['page']['liked'];
if( $liked ) {
echo('fan');
}
else {
echo('not a fan ') ;
}
What could the issue be?
I had the same problem. If you're using heroku's base php template get rid of this code, that enforces the https on production:
// Enforce https on production
if (substr(AppInfo::getUrl(), 0, 8) != 'https://' && $_SERVER['REMOTE_ADDR'] != '127.0.0.1') {
header('Location: https://'. $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
exit();
}
When the user doesn't uses the secure connection, this line redirects to another page losing the POST requests.
You can try and send the signed_request with with GET method if you want to keep it. It may look like this:
// Enforce https on production
if (substr(AppInfo::getUrl(), 0, 8) != 'https://' && $_SERVER['REMOTE_ADDR'] != '127.0.0.1') {
$signed_request = "";
if (isset($_REQUEST['signed_request'])){
$signed_request = "&signed_request=" . $_REQUEST['signed_request'];
}
header('Location: https://'. $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . "?" . $signed_request );
exit();
}
That's my solution.
Here is the code i used to post stories to facebook page wall from my website. i have installed facebook sdk like facebook.php and base_facebook.php etc files.My requirement is to post stories without logging into facebook.i have gone through many tutorials yet i couldnt find any solution for this .can you please help me in this.here is the code which i am using.
$appid = 'xxxxx'; //Application ID
$appsec = 'xxxxx'; // Application secret
$redirectUrl = 'http://test.com/admin/'; //Facebook redirects back to this page
$permissions = 'publish_stream'; // Permissions we will need
if(isset($_POST['FacebookPageID']) && strlen($_POST['FacebookPageID'])>10)
{
$_SESSION['FacebookPageID']=$_POST['FacebookPageID'];
$_SESSION['FacebookMessage']=$_POST['FacebookMessage'];
$_SESSION['FacebookTitle']=$_POST['FacebookTitle'];
}
if(!is_numeric($_SESSION['FacebookPageID']) || strlen($_SESSION['FacebookPageID'])<5)
{
die("<meta http-equiv=\"refresh\" content=\"2;URL=".$redirectUrl."\" />");
}
else
{
if(!isset($_GET["code"]))
{
$_SESSION['state'] = md5(uniqid(rand(), TRUE));
$RedirectToFacebook = "https://www.facebook.com/dialog/oauth?client_id=".$appid;
$RedirectToFacebook .="&redirect_uri=".urlencode($redirectUrl.'test.php');
die("<script type=\"text/javascript\">top.location.href='" . $RedirectToFacebook . </script>
<noscript><a href='".$RedirectToFacebook."'>Needs Permissioins</a></noscript>");
}
else
{
############## Facebook Page ID ############
$facebookPageID = $_SESSION['FacebookPageID'];
############## Wall Message ############
$facebookMessage = (empty($_SESSION['FacebookMessage']) || s trlen($_SESSION['FacebookMessage'])<5)?"Nice Facebook Wall Posting Script!":$_SESSION['FacebookMessage'];
$facebookTitle = (empty($_SESSION['FacebookTitle']) || strlen($_SESSION['FacebookTitle'])<5)?"Nice Facebook Wall Posting Script!":$_SESSION['FacebookTitle'];
if($_SESSION['state'] !="")
{
echo $_SESSION['state'];
// $siteurl=$_GET['realurl'];
$AccessTokenUrl = "https://graph.facebook.com/oauth/access_token?client_id=".$appid;
$AccessTokenUrl .="&redirect_uri=".urlencode($redirectUrl.'test.php');
$AccessTokenUrl .="&client_secret=".$appsec;
$AccessTokenUrl .="&code=".$_GET["code"];
$ReturnedString = file_get_contents($AccessTokenUrl);
$params=null;
parse_str($ReturnedString, $params);
$OurAccessToken = $params['access_token']; //access token
//---------------
require_once('src/facebook.php' ); //Include our facebook Php Sdk
$post_url = '/'.$facebookPageID.'/feed';
$facebook = new Facebook(array(
'appId' => $appid,
'secret' => $appsec,
));
//the Posting Parameters
$PostData = array(
'message' =>$facebookMessage,
'name' => $_SESSION['title'],
'caption' => "testcom",
'link' => 'from tranz',
'description' => $facebookMessage,
' picture' => "http://test/uploads/".$_SESSION['imageshare']."",
'access_token' =>$OurAccessToken,
'actions' => array(
array(
'name' => 'Saaraan',
'link' => 'http://www.saaraan.com'
)
)
);
//print_r($PostData); exit;
try {
$result = $facebook->api($post_url, 'post', $PostData);
//$result = $facebook->api('me/feed','post', $PostData);
if($result)
{
// session_destroy();
echo 'Done..';
die("<meta http-equiv=\"refresh\" content=\"2;URL=".$redirectUrl."? success=1&fbp=".$facebookPageID."\" />");
}
}
catch (Exception $e)
{
echo 'Facebook could be experiencing some problem! Try again later <br />Facebook Says: '. $e->getMessage();
}
//--------------
}
}
Facebook requires users to be authenticated to post something. No, it is not possible to post without authentication, if authentication is what you mean by "logging in."