Service account API error when getting the access token - google-cloud-platform

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.

Related

Facebook SDK not getting permissions

I'm using "facebook/php-sdk-v4": "dev-master".
Here is my code.
$this->helper = new Facebook\Helpers\FacebookRedirectLoginHelper('http://localhost:8000/test2');
$this->helper->getLoginUrl(['scope'=>'user_about_me,user_groups'])
//test2 controller
session_start();
$session = $this->facebook->getSessionFromRedirect();
$request = new Facebook\FacebookRequest($session, 'GET', '/me/groups/');
$response = $request->execute();
$graphObject = $response->getGraphObject();
Here is the login link:
https://www.facebook.com/v2.0/dialog/oauth?client_id=335104339978143&redirect_uri=http%3A%2F%2Flocalhost%3A8000%2Ftest2&state=0d09d4965509ccb3dc78f2fffc44c11e&sdk=php-sdk-4.1.0-wip&scope=user_about_me%2C+user_groups
When I use the fb account that I registered the app, I can get the groups and the permission on login popups. But when I use other facebook accounts, the permission does not popup and I get no result.
You are asking for additional permissions in the incorrect way. You need to do the following using Facebook PHP SDK v4.0.9:
// generate login url with scope, each permission as element in array
$loginUrl = $helper->getLoginUrl( array( 'email', 'user_friends' ) );
// output login link
echo 'Login';
Source

How can I get my facebook personal profile posts using getAccessToken()?

What I am actually trying to do is to retrieve my posts/statuses from my personal facebook profile page (this is not a fan page) and display them in my website. Also please note that every user that will visit my website should be able to view my statuses by means it does not have to do with authenticating them or something like that. This is something that needs to be generated server-side.
I am aware that you can retrieve a JSON string from a URL like this https://graph.facebook.com/MY_PROFILE_ID/feed?access_token=ACCESS_TOKEN because I tried it from the facebook developers (Graph API Explorer) page and it is exactly what I need.
The thing is that when I generate the access token from the Graph API Explorer I can select permissions and it generates the token respectively according to permissions chosen, such as user_status, status_update, etc.
Now I want to accomplish this by using PHP-SDK but I have no idea how to generate an access token the same as the one I generate in the Graph API Explorer.
The basic way to do this is by calling getAccessToken() as shown here. The thing is that when I use the token generated from this simple method the JSON string returned will only show me my basic information.
$config = array(
'appId' => 'MY_APP_ID',
'secret' => 'MY_APP_SECRET',
);
$facebook = new Facebook($config);
$ACCESS_TOKEN = $facebook->getAccessToken();
How can I add permissions for instance? Should I assign parameters somewhere? I spent quite a lot of time reading the facebook API documentation and some other forums but I did not find the answer that I need.
Finally if I get the right access token than I would simply retrieve the JSON string and parse it with what I need.
Thanks.
you need for add permissions in your code for login using the fb js sdk add in the scope this like this example:
$("#login").on('click',function(){
FB.login(function(response){
console.log(response);
},{scope: 'email,manage_pages,read_insights'});
});
or in php fb sdk the next form:
<?php
require 'server/fb-php-sdk/facebook.php';
$app_id = 'APP_ID';
$app_secret = 'APP_SECRET';
$app_namespace = 'APP_NAMESPACE';
$app_url = 'https://apps.facebook.com/' . $app_namespace . '/';
$scope = 'email,publish_actions';
// Init the Facebook SDK
$facebook = new Facebook(array(
'appId' => $app_id,
'secret' => $app_secret,
));
// Get the current user
$user = $facebook->getUser();
// If the user has not installed the app, redirect them to the Login Dialog
if (!$user) {
$loginUrl = $facebook->getLoginUrl(array(
'scope' => $scope,
'redirect_uri' => $app_url,
));
print('<script> top.location.href=\'' . $loginUrl . '\'</script>');
}
?>
the most important for add permission is this part :
$scope = 'email,publish_actions';
you can find all about the extended permissions in this link
https://developers.facebook.com/docs/reference/login/extended-permissions

Box API newbie connection problems

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.

Facebook API - App using Oauth to update status of page

I have built an app using the PHP Facebook SDK. It allows users to authenticate my app with facebook OAth so that they can update their status' via my App. This works great, however a lot of my users have business pages and they want to update the status on their business page not their main personal feed. How is this possible? Below is what I have so far.
if ($status != ''){
try {
$parameters = array(
'message' => "$status"/*,
'picture' => $_POST['picture'],
'link' => $_POST['link'],
'name' => $_POST['name'],
'caption' => $_POST['caption'],
'description' => $_POST['description']*/
);
//add the access token to it
$parameters['access_token'] = $access_token;
//build and call our Graph API request
$newpost = $facebook->api(
'/me/feed',
'POST',
$parameters
);
$success['status'] = "$xml->status";
$xml2 = new XMLGenerator($success, 'facebook','status');
$returnData = $xml2->output;
$returnData = APIResponse::successResponse('200', "$xml->status");
} catch (Exception $e) {
$returnData = APIResponse::errorResponse('400', 'Facebook Error: '.$e);
}
I assume I would have to change '/me/feed'? but to what? What is they have multiple pages how would my app know which page to post to?
Any help with this would be much appreciated.
You can substitute me with the PAGE_ID to post to a page e.g., /013857894/feed. Make sure that you have completed the OAuth process with the manage_pages and publish_stream permissions. You can learn more at the link below:
https://developers.facebook.com/docs/reference/api/page/#statuses
If the user has multiple Pages then you will first need to give them some way of selecting which page they want to post to. You can find out which Facebook Pages a given user is the administrator of by calling /me/accounts for that user. You can find out more about this approach in the Connections section of this page:
https://developers.facebook.com/docs/reference/api/user/

Can't Authenticate through Facebook PHP SDK

I currently force users to authenticate through Facebook each time they start a new session with my site. This means I force users to hit the url obtained through $facebook->getLoginURL() each time the browser is restarted.
When a user completes the login process, they are redirected to my login script:
{checks for CSRF token and error status...}
$facebook = new Facebook(array(
'appId' => '{my app id}',
'secret' => '{my app secret}',
'cookie' => true
));
//Get user info
$user = $facebook->getUser();
if($user)
echo 'user found';
else
echo 'no user!';
$user always results in 0; I am getting the expected 'state' variable and no errors in the API response. Also, I see that the relevant App permissions exist on my profile. However, $facebook->getUser() still returns 0. Is there some intermediate step that I'm missing (am I expected to do anything with the user's auth token?)
I know there are many threads on this problem but haven't found any resolutions. Also, I think this is a very basic example so I'm hoping the answer here will be more useful for future users dealing with the problem. Thanks!