Box API newbie connection problems - web-services

I'm trying to connect to the box-api to read the files of my user in my folder. I've created the folder and uploaded the files, then i went to the OAuth2 interface to obtain an API Key. It has given the api key to me so i pasted it in the code:
public function indexAction()
{
try {
$uri = "https://api.box.com/2.0/folders/0/items?limit=100&offset=0";
$config = array(
'adapter' => 'Zend_Http_Client_Adapter_Curl',
'curloptions' => array(CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTPHEADER=>array("Authorization: Bearer MYKEY"),
CURLOPT_SSL_VERIFYPEER, false,
CURLOPT_USERPWD, "user:password"),
);
$client = new Zend_Http_Client($uri, $config);
$response = $client->request();
$text= $response->getBody();
} catch (Zend_Exception $e) {
echo "Message: " . $e->getMessage() . "\n";
// Other code to recover from the error
}
}
Following this tutorial on youtube.
The error i'm getting is the following:
Message: Error in cURL request: unable to use client certificate (no key found or wrong pass phrase?)
I registered the application with the name "test". What have I done wrong? What am I missing?

You might try passing the request without the CURLOPT_SSL_VERIFYPEER and CURLOPT_USERPWD options. I don't think those are strictly necessary -- to my knowledge Box doesn't do any client certificate validation -- and they may be causing the problem.

The use of Zend http client by itself is better than using the curl adapter.Besides the username and password are not required to authenticate. You can perform the operation only after you have received th access token from the authorization procedure of Oauth2 of Box-API. The zend http client call that can be used is the following:
$client = new Zend_Http_Client('https://api.box.com/2.0/folders/0');
$client->setMethod(Zend_Http_Client::GET);
$client->setHeaders('Authorization: Bearer '.$access_token);
$response = $client->request()->getBody();
My 2 cents.

Related

Service account API error when getting the access token

I am testing google people API for our web application.
Steps:
I created new project in the google console (https://console.cloud.google.com/)
I enabled People API
I created needed Credentials - web client for my application and API key
I created service account with p12 key for server to server queries and enabled "Google Workspace Domain-wide Delegation"
I configured OAuth consent screen with scopes needed to authorize to google and get access to people API: /auth/userinfo.email /auth/userinfo.profile /auth/contacts /auth/contacts.readonly
Then my PHP script using "Google API PHP client" make redirect link to consent screen and return code for access token with Web client:
<?php
$client = new Google_Client();
$client->setAccessType('online'); // default: offline
$client->setApplicationName('My Project xxxxx');
$client->setClientId('999999999999-qwertysdfhwe9uriiiiiiiiiiiiiiiii.apps.googleusercontent.com');
$client->setClientSecret('GOCSPX-hhhhhhhhhhhhhhhhhhhhhhhhhhhh');
$client->setDeveloperKey('AIzafffffffffffffffffffffffffffffffffff'); // API key
$client->setState('subdomain.myapp.com');
$scriptUri = 'https://oauth.myapp.com/auth.php';
$client->setRedirectUri($scriptUri);
$client->addScope('https://www.googleapis.com/auth/userinfo.email');
$client->addScope('https://www.googleapis.com/auth/userinfo.profile');
$client->addScope('https://www.googleapis.com/auth/contacts');
$auth_url = $client->createAuthUrl();
header('Location: '.$auth_url);
?>
This code redirects to google Authentication screen, then I login with google and approve scopes. Google redirects me back to my app and now I have access token and aproved scopes and email of authenticated user.
The next step I have huge trouble - server - to - server query to get access token for people API
function base64_url_encode($input) {
return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
}
$iat = time();
$url = "https://www.googleapis.com/oauth2/v4/token";
$scope = 'https://www.googleapis.com/auth/contacts';
$jwt_data = array(
'iss' => '111111111111111111111', // My service account ID
'aud' => $url,
'scope' => $scope,
'exp' => $iat + 3600,
'iat' => $iat,
'sub' => 'user#gmail.com', // Email of the user that was autenticated in first step
);
openssl_pkcs12_read(file_get_contents('keyfile.p12'), $certs, 'notasecret');
$header = array('typ' => 'JWT', 'alg' => 'RS256');
$signing_input = base64_url_encode(json_encode($header)) . '.' . base64_url_encode(json_encode($jwt_data));
openssl_sign($signing_input, $signature, $certs['pkey'], 'SHA256');
$jwt = $signing_input . '.' . base64_url_encode($signature);
$data = array(
"grant_type" => "urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion" => $jwt
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
curl_close($ch);
$google_contacts_api_tokens_collection[$use_mailbox] = $response;
return $response;
And this code google returns the error that I can not fix, and I have no any ideas.
The text of error:
"Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested."
Your code is trying to impersonate a user via a service account. This requires enabling Domain Wide Delegation. In a round-about way, the error message means the service account does not have permission because delegation is not enabled.
Perform Google Workspace Domain-Wide Delegation of Authority
If the user is not part of Google Workspace, then you cannot impersonate the user.
Yes, but I already tried this and it does not help. I configured scopes for service account in the Google Workspace, and also checked the "Enable Google Workspace Domain-wide Delegation" checkbox in google console. In Google Workspace I used digital Client ID of my service account.
And also I discovered one strange moment:
Web client always returns good access token, but when I request service account access token it works well only for google console project owner ('sub' => 'project.owner#gmail.com'). And if I request service account access token for another user ('sub' => 'project.testuser#gmail.com') Google also returns the same error: Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested.

Accessing USI Webservice using a Token from Vanguard returns an Error

So I was trying to connect our SMS (Student Management System) to a government Service or Site. The process requires an authentication token coming from Vanguard. Successfully, I am able to obtain the token... but due to lack of documentation and sample codes in PHP I am having problem communicating to the said service. I was wondering if is it my code that causes the problem or is it my calls that has conflict interfacing to the webservice: Please see code below:
<?php
require_once 'VanguardClient.php';
$endpoint = 'https://3pt.portal.usi.gov.au/Service/v2/UsiService.svc';
function get_sts($endpoint){
$test = true;
$auskey_path = 'Keystore.xml';
$auskey_password = 'Password1!';
$v = new VanguardClient($test);
$v->loadAuskey($auskey_path, $auskey_password);
try {
return $v->requestToken($endpoint);
} catch (SoapFault $e) {
echo "Error1:";
echo $e;
}
}
//get token from Vanguard
$token = get_sts($endpoint);
//create soap client
try{
$wsdl = 'https://3pt.portal.usi.gov.au/service/V2/UsiService.wsdl';
$client = new SoapClient($wsdl,
array(
'trace' =>1,
//'soap_version' => SOAP_1_2,
'keep_alive' => false,
//'connection_timeout' => 500000,
'cache_wsdl' => WSDL_CACHE_NONE
)
);
} catch (SoapFault $e) {
echo "SoapClient Error:<br />";
var_dump($e);
}
try {
$result=$client->__setSoapHeaders( $token );
} catch (SoapFault $e) {
echo "__setSoapHeaders:";
var_dump($e);
}
$data = array(
'OrgCode' => '970003',
'USI' => 'U6Q8JN6UD9',
'FirstName' => 'Myrna',
'FamilyName' => 'Macknight',
'DateOfBirth' => '1971-04-19'
);
try{
$response=$client->__soapCall('VerifyUSI',$data);
} catch (SoapFault $e) {
echo "__soapCall Error:<br />";
echo $e;
}
var_dump($response);
The result on the browser that I am seeing is this:
SoapFault exception: [HTTP] Cannot process the message because the content type 'text/xml; charset=utf-8' was not the expected type 'application/soap+xml; charset=utf-8'. in /var/www/html/usitest/example1.php:73 Stack trace: #0 [internal function]: SoapClient->__doRequest('__soapCall('VerifyUSI', Array) #2 {main}NULL
Thanks in advance guys!!!
Your content type is probably caused by the SOAP version.
Try setting the SOAP version to 1.2:
'soap_version' => SOAP_1_2
See SoapClient connection to SoapServer
However, I think there are other issues in your code - particularly with the Vanguard token.
We managed to solve this however it took many classes, templates, external packages and months of work to solve and is not something we can put up online. However there are some things I'd suggest you do to solve it in your situation.
This does not work like a normal SOAP service. Use XML templates for all steps of the various process (Vanguard, USI, components of these sections etc).
Reverse engineer the .Net example code, we had major issues with the Java code.
We made major headway by using a proxy and capturing the content sent and received.
Unless you are using composer to manage your security dependencies you're going to have a bad time, even with composer it was a pain.
There are about 10 sections to do with security that have to be reverse engineered, don't forget to canonicalise the content to get the encryption correct.
Use Guzzle for the requests, it's easier
Most of the stuff in the PHP example is wrong, or at least impossible to follow and debug to fix. At the end we couldn't see a way that it would work.
Expect to spend at least a couple of weeks on it and you need to know a lot about security, hashing and ssl certificates.
Sorry I can't give you a full working solution but knowing these steps above would have definitely helped us and so I hope they'll help you.

facebook-php-sdk serverside graph api call with app token

I'm trying to show the feed and events of a Facebook fanpage on a website. I'm using the php sdk to call the Facebook graph api. I also created an app on my Facebook account and have an app ID, app secret and app token.
I don't want to log in the user of the website. I just want to integrate the events and news data of the Facebook fanpage on the website.
My question is: Can I use the static app token to make graph api calls with php from my server and build my website after that, so that no one will receive the app token? Or is this bad because of security issues?
Here is the code:
$app_ID = '{appID}';
$app_secret = '{appSecret}';
$app_token = "{staticAppTokenFromFacebookDeveloperSettings}";
$facebook_page_ID = '{facebookPageID}';
$fb = new Facebook\Facebook([
'app_id' => $app_ID,
'app_secret' => $app_secret,
'default_graph_version' => 'v2.7',
]);
$fb->setDefaultAccessToken($app_token);
try {
$response = $fb->get('/' . $facebook_page_ID . '/feed');
//$response = $fb->get('/' . $facebook_page_ID . '/events');
// ...
} catch(Facebook\Exceptions\FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
Thank you very much!
You have to put the App Secret somewhere in order to use an App Access Token, and the server is the only place where it is safe. Just keep in mind that there are limits to API calls, you should cache results in your own database. Do not call the feed and events endpoints for every single user hit.

having trouble sending facebook notification via ajax call to php

In my javascript I have a click event that triggers an ajax call to the php page where I send my notification from. I chose to do it this way because the documentation advises against using your app secret in any client side code, and the notifications parameters requires an access token that you can only get using the app secret.
The problem I'm having is that even though I'm logged in, $facebook->getUser() is returning 0 in php, so the api call I make afterwards to send the notification wont work. My user is already logged in via the client side code, so how do I get the message to the php that they're logged in so the notification can be sent.
//JS
$.ajax({
url : "http://xxxxxo/bn/notification.php",
type : 'POST',
data: {notify: notify },
success : function (result) {
console.log(result);
},
error : function () {
alert("error sending notification");
}
});//closes ajax
//PHP
<?php
require_once(dirname(__FILE__).'/php-sdk/facebook.php') ;
$APPLICATION_ID = '1402xxxxx7';
$APPLICATION_SECRET = 'ce71d6bbxxxxx5f55a';
$fb_app_url = "http://apps.facebook.com/myAPP";
$config = array();
$config['appId'] = $APP_ID;
$config['secret'] = $APP_SECRET;
$config['cookie'] = true;
$facebook = new Facebook($config) or die('Error is here!');
$facebook = new Facebook(array(
'appId' => $APP_ID,
'secret' => $APP_SECRET,
'fileUpload' => true
));
$notify = $_REQUEST['notify'];
$userid = $facebook->getUser();
/*IF WE HAVE A LOGGED IN USER AND THE 'NOTIFY' REQUEST VALUE, THEN SEND THE NOTIFICATION.
BUT MY USER ID IS 0. HOW DO I GET PHP TO RECOGNIZE ME AS LOGGED IN WITHOUT HAVING TO FORCE MY USER TO LOG IN VIA PHP AFTER THEY'VE ALREADY LOGGED IN CLIENT SIDE?*/
if($userid && $notify){
$token_url ="https://graph.facebook.com/oauth/access_token?" .
"client_id=" . $APP_ID .
"&client_secret=" . $APP_SECRET .
"&grant_type=client_credentials";
$app_token = file_get_contents($token_url);
$app_token = str_replace("access_token=", "", $app_token);
$data = array(
'href'=> 'https://apps.facebook.com/thebringernetwork/',
'access_token'=> $app_token,
'template'=> 'test'
);
$sendnotification = $facebook->api('/1622649653/notifications', 'post', $data);
}else{
//handle error
}
?>
The first thing I noticed is that you define your app id as $APPLICATION_ID but use it as $APP_ID (and the same goes for your app secret). But since you didn't mention any errors and $facebook->getUser(); executes I'm guessing this is just a bad copy-paste.
Now for the sake of answering this question I'm going to presume that you are using the latest versions of both JS and PHP SDKs. These use oauth 2.0 and change the way you pass the login information from JS to PHP.
According to Facebook Developer Blog removing $config['cookie'] = true; and setting oauth to true in your JS configuration should work. Just make sure to refresh the site after the login.
The solution I've found in my own project is to disable cookies altogether and simply pass the access token to my PHP script.
In your JS call your PHP script like this (make sure to call this after the JS login!):
$.ajax({
url : "http://xxxxxo/bn/notification.php",
type : 'POST',
data: {
notify: notify,
token: FB.getAuthResponse()['accessToken'] // add your access token
},
success : function (result) {
console.log(result);
},
error : function () {
alert("error sending notification");
}
});
And in your PHP script add this after creating the FB object.
$facebook->setAccessToken($_POST['token']); // set the users access token
Doing things this way will also get rid of any need to refresh the website after the login.
Yes, this is a common problem when using the PHP SDK in combination with AJAX:
When you make an AJAX request, the PHP SDK deletes the cookies where the authorization information are stored, and then the next call to getUser will just return 0, because this method tries to find the current user id in those cookies – apparently there is something in the OAuth 2.0 spec that demands this behavior to prevent some sort of click-jacking attack.
But the info will still be stored in the session, so you can read the user id (and the user access token, should you need it) from there:
$user_id = $_SESSION['fb_YourAppIdHere_user_id'];
$user_access_token = $_SESSION['fb_YourAppIdHere_access_token'];
Replace YourAppIdHere with your app id (so it becomes fb_1234567890_user_id resp. fb_1234567890_access_token) to get the correct names of those session keys.

Facebook OAuthException: (#1)

I have a few applications which upload image to user profile. A few hours ago all applications were working fine but now when uploading is requested, it gives this error
Fatal error: Uncaught OAuthException: (#1) An unknown error occurred thrown in applications/fb-sdk/facebook.php on line 543
I'm using the following code to publish image.
$FILE = "images/$image";
$args = array('message' => 'My msg ');
$args['image'] = '#' . realpath($FILE);
$data = $facebook->api('/'.$uid.'/photos', 'post', $args);
Is it because of some policy change or some new feature?
I have all the permissions like upload is set to true and application takes permission to upload file.
P.s: when the application is used 2nd time, it works fine.
You need to verify if the user is logged in AND has the permissions to post on wall. We're going to do that with a TRY/CATCH with a call to the user.
$userId = $facebook -> getUser();
if ($userId) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
$userId = NULL;
error_log($e);
}
}
$app_permissions = array(
'scope' => 'publish_stream'
);
$logoutUrl = $facebook->getLogoutUrl();
$loginUrl = $facebook->getLoginUrl($app_permissions);
If the user is not logged in OR has authorized the app, you'll need to redirect him via header redirect or with a link.
if ($userId){
//Then you can call the facebook api
$data = $facebook->api('/'.$uid.'/photos', 'post', $args);
//... ...
}
That's the easiest way i've found.
EDIT : This question on stack has helped me : Facebook PHP SDK Upload Photos
No, the error is caused by the system cannot get the image file. Facebook will not allow the empty image field appear in the api. So it return Fatal error: Uncaught OAuthException: (#1) --- although it does not relate to the OAuth and OAuthException.