Google authentication from PHP - php

I know there are a lot of similar questions here in SO but I tried these solutions for hours but they didn´t work for me. I always get a { "error" : "unauthorized_client" }". I want to programmatically refresh my accesstoken to use the Youtube API. I already have gained a refreshtoken.
This is what I´ve come up with:
$ch = curl_init();
curl_setopt($ch, CURLOPT_POSTFIELDS, array(
'client_secret' => '<mysecret>',
'grant_type' => 'refresh_token',
'refresh_token' => '<my_refresh_token>',
'client_id' => '<my_client_id>.apps.googleusercontent.com',
'redirect_url'=>'<my_redirect_uri>'
));
curl_setopt($ch, CURLOPT_URL, 'https://accounts.google.com/o/oauth2/token');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
echo var_dump(curl_exec($ch));
Whats wrong with it?

The URL and query params you've indicated look right to me. Seems like this error would come up if the client_id you provide to generate new tokens is different than the client_id provided to obtain the refresh_token.
One thing that might be happening is that if you have generated an access_token and refresh_token using Google's OAuth playground, and then trying to use that refresh_token to generate new tokens -- this will not work. The Google OAuth playground is using different client_ids to make that request, and this will definitely result in the "unauthorized_client" error you've documented.
Temboo has a very concise and easy-to-use OAuth library for Google. You can check it out here: https://www.temboo.com/library/Library/Google/OAuth/.
(Full disclosure: I work at Temboo)

Related

Google Play Store reviews API in PHP

Currently I am trying to get reviews from https://play.google.com/store/apps/details?id=com.rosterelf.android.phone&hl=en by following https://developers.google.com/android-publisher/api-ref/rest/v3/reviews/list documentation.
I am using the PHP (cURL) method but I am keep getting an error saying --- Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential.
Below are my steps what I have done / tried so far.
Created one Api KEY, OAuth 2.0 Client ID and Service Account in Google Developer Console.
Enabled the Google Play Android Developer API and Google Play Custom App Publishing API too.
Going at my browser https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/androidpublisher&response_type=code&redirect_uri=REDIRECT-URI&client_id=CLIENT-ID
It gives me the code in response and then to be able to get access_token, I am using below PHP cURL code which is also working fine.
<?php
$client_id = 'CLIENT-ID';
$redirect_uri = 'REDIRECT-URL';
$client_secret = 'CLIENT-SECRET';
$code = 'CODE';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://accounts.google.com/o/oauth2/token");
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, array(
'code' => $code,
'client_id' => $client_id,
'client_secret' => $client_secret,
'redirect_uri' => $redirect_uri,
'grant_type' => 'authorization_code'
));
$data = curl_exec($ch);
var_dump($data);
exit;
And in response, I am successfully able to get the access_token.
Now I am trying to go directly to this page in browser https://www.googleapis.com/androidpublisher/v3/applications/com.rosterelf.android.phone/reviews?access_token=ACCESS-TOKEN but it keeps saying me...
Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project
-> I have checked the roles and permissions and it has owner as a permission in service account.
-> My REDIRECT-URI also the same URL throughout this process.
I event tried this URL to fetch the reviews https://androidpublisher.googleapis.com/androidpublisher/v3/applications/com.rosterelf.android.phone/reviews/review?access_token=ACCESS-TOKEN but having the same error.
Can someone please guide me what am I missing from here and why I am getting here and what exactly I should do from here on to get the reviews ?
Any help or suggestions will be highly appreciated.
Thanks in advance.
This is an example for that API using the official client library. I believe this code is for service account authentication. The service account will need to be properly configured see using_a_service_account How to create service account credetinals just remember to enable the proper library.
<?php
require_once 'google-api-php-client-2.2.2\vendor\autoload.php';
putenv('GOOGLE_APPLICATION_CREDENTIALS=client_secret.json');
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->addScope(Google_Service_AndroidPublisher::ANDROIDPUBLISHER);
$android_publisher = new Google_Service_AndroidPublisher($client);
$response = $android_publisher->reviews->listReviews('appname');
echo "<pre>";
var_dump($response);

Login via Google: what to do after getting access token?

I am learning to build a Login via Google button on my Joomla website, and I am following instruction on https://developers.google.com/identity/protocols/oauth2/web-server.
A little background:
I am using a third party extension to handle social login. Its facebook login works well, but its google login is outdated, still trying to connect to Google Plus endpoints. Clicking the login button on my page does lead to Google's account choice screen, after I choose an account and grant permission, there is a simple error message on the callback page. The author has stopped updating the extension, so for learning purpose, I've decided to fix it myself.
What I've achieved:
Currently I was able to get the access token from Google.
.......
$postdata = array(
'grant_type' =>'authorization_code',
'client_id' => $this->params->get('goappid'),
'client_secret' => $this->params->get('gosecret'),
'redirect_uri' => $this->getRedirectURL().'&task=gologin',
'code' => $_GET['code']);
curl_setopt($curl, CURLOPT_URL, 'https://oauth2.googleapis.com/token');
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded'));
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postdata));
$oauth = json_decode(curl_exec($curl));
// Above code seems to be fine,  getting $oauth response as follows
//   "access_token": "token string",
//   "expires_in": 3599,
//   "scope": "https://www.googleapis.com/auth/userinfo.profile",
//   "token_type": "Bearer",
// "id_token":"token string" 
if (isset($oauth->access_token)) {
curl_setopt($curl, CURLOPT_POST, false);
curl_setopt($curl, CURLOPT_URL, 'https://www.googleapis.com/plus/v1/people/me?access_token='.$oauth->access_token); //Apparently outdated endpoint
$user = json_decode(curl_exec($curl));
if (empty($user->error)) {
curl_setopt($curl, CURLOPT_URL, 'https://www.googleapis.com/plus/v1/people/me/activities/public?access_token='.$oauth->access_token);//Apparently outdated endpoint
My question: At this point, I don't know what to do. The instruction says After your application obtains an access token, you can use the token to make calls to a Google API on behalf of a given user account, but how do I "make calls to a Google API"? To make a simple login via Google button, which API should I call? And to what endpoint should I make the request? I can't find this information from the instruction page. Above code is making request to https://www.googleapis.com/plus/v1/people/me?access_token, which is obviously outdated but how should I change this? This should have been provided by the instruction but I couldn't find it. And if I want to access other Google APIs, how do I "make calls" to them? a.k.a where do I find endpoints for each API?
I've also read https://developers.google.com/identity/protocols/oauth2/openid-connect, is what I am trying to do considered OIDC? Should I proceed according to this document?
I still think that access_token in the query path works in some Google apis. until June 2021
GET https://www.googleapis.com/plus/v1/people/me?access_token=[token]
I recommend switching to using an authorization header
GET https://people.googleapis.com/v1/%5BRESOURCENAME%5D HTTP/1.1
Authorization: Bearer [YOUR_ACCESS_TOKEN]
Accept: application/json

How to authorize post request in REST API?

I'm sitting here working on making a post request in a rest api in php using curl. For this purpose I have the api key and an auth key, which I am currently including as post values in the request. But I keep getting HTML back in my response instead of JSON data (which its supposed to be) giving me a 401 unauthorized error.
I've noticed often you need to make custom headers to authorize yourself in these cases (I'm guessing I need to use my auth key for that, in the header somehow).
This is my code:
$post = [
'apikey' => $apiKey,
'authkey' => $authKey,
'name' => $reknr,
'description' => $opgave,
'clientId' => $clientId,
'orderTypeId' => $typeId,
'contactAddressId' => $addressId,
'theirref' => $ref,
'reqno' => $reknr
];
// Set api link
$ch = curl_init('https://app.minuba.dk/api/1/Order');
// Set return value to true
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Configure header
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Authorization: Basic '.$authKey,
'Content-Type: application/json')
);
// Add post fields
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
// execute!
$response = curl_exec($ch);
// close the connection, release resources used
curl_close($ch);
The API docs doesn't say anything about how you authorize yourself when making post request, during get requests its fairly easy you just include the apikey and authkey as normal parameters and it works fine.
My question is, how do I know how to configure my header so the API authorizes me? The docs say nothing about it or offers any explanation as to how except mentioning you need both the apikey and authkey to gain access.
I admit my understand of the http headers are limited, but how do I know how to configure it for this particular api?
UPDATE:
Found out the header response gives me this line:
WWW-Authenticate: Basic realm="Minuba REST API"
This tells me that the method I'm using to authenticate should be correct right? So why am I still getting a 401?

PHP/Salesforce connected App issues - {"error_description":"authentication failure","error":"invalid_grant"}

I've successfully implemented the oAuth2 authentication process using the Web Server Flow of the REST API in PHP between my application and Salesforce, and it's working great when connecting with a Developer Edition type Salesforce account.
However, it's not working when trying to connect a test or prod environment type Salesforce account: I can't get an access token with the authorization code given by Salesforce since Salesforce gives me this error:
{"error_description":"authentication failure","error":"invalid_grant"}
Does anybody have an idea why it's not working ?
Here's what I've done:
Step 1 => OK => Redirect user to Salesforce
Step 2 => OK => User logs in
Step 3 => OK => User is redirected to our application with the authorization code
Step 4 => NOT OK => We request an access token using the authorization code given by Salesforce
We have tried it all (maybe not though :D): we have checked all the security configuration on our end and on the customer's end, we have checked for IP restrictions (no IP restriction is used), we have given our App "Full Access", but still no luck. We are receiving the authorization code which is encoded correctly and seems normal.
Does anybody have an idea why it's not working ?
Do you know if I need to validate our connected App before it can be used by test or prod type Salesforce accounts ?
Thanks a lot for all your help in advance.
Cheers
Quentin
NOTE : This is a duplicate of the following issue I guess, but it got no answer :( https://developer.salesforce.com/forums?id=906F00000009AFvIAM
I also saw this but it didn't fix my issue Salesforce Authentication Failing
EDIT 1 :
Here's the code I use ($instance is 'https://test.salesforce.com' in our case):
$url = $instance . '/services/oauth2/token?format=json';
$postFields = array(
'code' => $code,
'grant_type' => 'authorization_code',
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'redirect_uri' => $this->redirectURL);
// Create the CURL object.
$handle = curl_init($url);
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($handle, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($handle, CURLOPT_POST, TRUE);
curl_setopt($handle, CURLOPT_POSTFIELDS, $postFields);
I feel pretty dumb answering my own question but that may help somebody someday.
In my "Edit 1", I was wrong about the content of $instance.
It was not pointing to 'https://test.salesforce.com', it was pointing to 'https://login.salesforce.com' so it was normal to get an "authentication failure" error.
So if you're experiencing the same problem, do check the URL you're sending the request to.

LinkedIn oAuth 2 issue with client_id parameter

I'm trying to create an application on LinkedIn that's using OAuth2 for authentication and am running into some errors. The client runs on an iOS device and uses an oAuth library to make a call to LinkedIn's servers. My iOS client successfully gets the authorization_code. The client application then passes that authorization_code to my server, which attempts to connect to linkedIN again and get the access_token. This step consistently fails, I get the following error from LinkedIn: {"error":"invalid_request","error_description":"missing required parameters, includes an invalid parameter value, parameter more than once. : client_id"}
My POST method to LInkedIN does contain the client_id, it only contains it once, and I've triple checked the values for all the parameters, they are correct. I've also reset the access multiple times from https://www.linkedin.com/secure/settings and I've even created additional applications on LinkedIn, I keep getting the same result.
I've checked other responses, such as this one: unable to retrieve access token linkedin api and tried the suggestions: revoke keys, request new keys etc, nothing seems to be working.
Here is my server code:
$tokenURL = 'https://www.linkedin.com/uas/oauth2/accessToken';
$redirectURL = 'https://staging.textsuggestions.com';
$clientId = '75a4ezqh741sup';
$clientSecret = 'XXXXXXXX';
$tokenArguments = array("grant_type" => "authorization_code",
"code" => $code,
"redirect_uri" => $redirectURL,
"client_secret" => $clientSecret,
"client_id" => $clientId);
// send the request to the server getting data
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $tokenURL);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $tokenArguments);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
if (!empty($response["error"])) {
error_log("Error is: " . $response["error"]);
exit (0);
} else {
// no error, get the access_token and do stuff with it
$timeout = $response["expires_in"];
$access_token = $response["access_token"];
}
Ok I realized what I was doing wrong, the client application library that I was using was generating the full access token (not the auth code). So I was trying to pass in the access token in the place of the auth code. The error that I was getting from Linked In was certainly misleading and I should have checked the client library I was using more carefully.
Have you tried to check your code against this code sample?
https://developer.linkedin.com/documents/code-samples
Check that the POST headers include "Content-Type": "application/x-www-form-urlencoded".

Categories