Trying to authentcate with my API without the frontend of my environment so I can test my API end points with postman or some sort of client. I have a Baerer token I took from my frontend axios requests but apparently Laravel wont take it and just returns Route login not defined IE meaning its trying to redirect to the login so it can't auth.
So I tried generating a new one with Insomnia, similar to postman since postman gave me the Route not defined issue so I gave up wih it.
Going to: http://api-core.test/api/oauth/token
Passing:
client_id=2
client_secret=...
grant_type=client_credentials
username=...#example.com
password=...
scope=
And now its just spitting out
{
"error": "unsupported_grant_type",
"message": "The authorization grant type is not supported by the authorization server.",
"hint": "Check that all required parameters have been provided"
}
I am following this example to get server-to-server access working between my PHP application and Google Cloud API's,
https://developers.google.com/api-client-library/php/auth/service-accounts. In particular, I need to access the Drive API.
When I run the application though I get the following error:
Google_Service_Exception : {
"error": "unauthorized_client",
"error_description": "Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested."
}
Here's what I have done:
Created a GCP project
Added a service account to the project, with domain wide delegation, and a set of keys
Enabled the Google Drive API in the project
In my G Suite account, under 'Manage API client access', I have added the Client ID of my service account, with the permission of https://www.googleapis.com/auth/drive
Have I missed a step?
Here's my code:
putenv('GOOGLE_APPLICATION_CREDENTIALS=my_storage/secure/my-app-service-account.json');
$client = new \Google_Client();
$client->setScopes(\Google_Service_Drive::DRIVE_METADATA_READONLY);
$client->useApplicationDefaultCredentials();
$client->setSubject('my_email#my_domain.com');
$drive = new \Google_Service_Drive($client);
echo $drive->about->get();
The example does not include the setScopes() call, however I was getting a scope-related error without it. (The example is not based on the Drive API, so perhaps it's not required in that case?)
UPDATE: In the IAM settings for the GCP, I added the email address of the service account as a Project Owner, but that made no difference.
I found the problem.
In the setScopes() call above, the value passed needs to be the same as the value given when setting up the client in G Suite, in this case https://www.googleapis.com/auth/drive
I'm using this php wrapper, successfully getting a code from pinterest using the link generated according to the docs:
$loginurl = $pinterest->auth->getLoginUrl($callback_url, array('read_public'));
Then when I run this:
$token = $pinterest->auth->getOAuthToken($_GET['code']);
It works fine on my local server, but when I try to run it on our Dreamhost server, I get:
Pinterest error (code: 403) with message: Forbidden
I looked through the error documentation Pinterest supplies, but I can't find anything relating to 403 errors when retrieving oauth tokens.
The only two places I've seen mention of 403 errors when requesting oauth tokens from Pinterest's API have concluded that Pinterest is blocking the ips or the user agent string.
I've tried manually overriding the user agent string to no avail.
I've tried contacting Pinterest to find out if there is anything I'm missing and they directed me here.
Make sure the Dreamhost server is using an HTTPS URL e.g. is using TLS. That could be the reason why you get a 403.
I'm querying the Analytics API via a Service Account.
I have written the code on the dev server and it works without issues.
When running the same code on the production server, it throws this:
Google_AuthException: Error refreshing the OAuth2 token, message: '{
"error" : "invalid_grant" }'
I've tried creating another Service account, and the behavior is the same.
The oAuth IETF draft (https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-31) says this about the error:
invalid_grant
The provided authorization grant (e.g. authorization
code, resource owner credentials) or refresh token is
invalid, expired, revoked, does not match the redirection
URI used in the authorization request, or was issued to
another client.
Here is the code I've written:
$GA_CLIENT_ID = 'XX.apps.googleusercontent.com';
$GA_APP_EMAIL = 'XX#developer.gserviceaccount.com';
$GA_APP_NAME = 'XX';
$GA_KEY_FILE = 'XX';
// create client object and set app name
$client = new Google_Client();
$client->setApplicationName($GA_APP_NAME); // name of your app
// set assertion credentials
$client->setAssertionCredentials(
new Google_AssertionCredentials(
$GA_APP_EMAIL, // email you added to GA
array('https://www.googleapis.com/auth/analytics.readonly'),
file_get_contents($GA_KEY_FILE) // keyfile you downloaded
));
// other settings
$client->setClientId($GA_CLIENT_ID); // from API console
$client->setAccessType('offline_access'); // this may be unnecessary?
// create service and get data
$service = new Google_AnalyticsService($client);
$result = $service->data_ga->get($ids, $startDate, $endDate, $metrics, $optParams);
return $result;
I've also tried a solution suggested here (https://groups.google.com/forum/?fromgroups#!topic/gs-discussion/3y_2XVE2q7U%5B1-25%5D) using authenticatedRequest() instead of Google_AnalyticsService:
$req = new Google_HttpRequest($apiUrl);
$resp = $client::getIo()->authenticatedRequest($req);
$result = json_decode($resp->getResponseBody(), true);
This alternative also works on the dev server, but not on the production one.
I am totally clueless on this one. Has anyone seen this/fixed it?
Thanks!
Apparently the problem was the system time being off. Worked by sync-ing via NTP with:
sudo ntpdate npt.ubuntu.com
sudo ntpdate pool.ntp.org
Edit
As #RafaSashi suggested below, the pool.ntp.org server is more reliable. Use that instead of ntp.ubuntu.com (which was the first working one I tried, thus the initial choice).
The invalid grant can also be caused if you use the wrong "ServiceAccountId". It should be the email associated with the client id in the service account client id in the google apis access page. You'd also have to add this user to the google analytics account that you're planning to access.
This tripped me up because I assumed the email address they were referring to was the email address of my google account, since I used the same google account to get api access as I do for google analytics. I know Vir's already figured his out, just thought I'd add this in case someone else comes across the same question and, like me, their computer seems to be in sync with NTP.
In addition to Valer's answer:
First, you’ll need to install NTP if it isn’t already installed. For Debian or Ubuntu, that would be this command:
sudo apt-get install ntp
For Redhat or CentOS, you’ll need to use this one:
yum install ntp
If the synchronization via npt.ubuntu.com doesn't work try :
sudo ntpdate pool.ntp.org
Resources
http://www.howtogeek.com/tips/how-to-sync-your-linux-server-time-with-network-time-servers-ntp/
https://www.digitalocean.com/community/tutorials/how-to-set-up-time-synchronization-on-ubuntu-12-04
There are two major reasons for invalid_grant error which you have to take care prior to the POST request for Refresh Token and Access Token.
Request header must contain "content-type: application/x-www-form-urlencoded"
Your request payload should be url encoded Form Data, don't send as json object.
RFC 6749 OAuth 2.0 defined invalid_grant as:
The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
I found another good article, here you will find many other reasons for this error.
https://blog.timekit.io/google-oauth-invalid-grant-nightmare-and-how-to-fix-it-9f4efaf1da35
Google Playground is best tool which help you how to send request.
https://developers.google.com/oauthplayground
I'm using abraham's twitter oauth class (https://github.com/abraham/twitteroauth) to connect and update twitter. I had it working during testing but now I'm trying to put it onto my live server I'm getting a 401 Could Not Authenticate error.
The original connection works ok (200 response) but when I use $connection->get('account/verify_credentials'); it just 401's and says it cannot authenticate.
From looking at the $connection object, the [consumer] callback_url property is blank. Could this be the problem?
Cheers
Apparently I didnt need to be running this unless I've already authenticated once through twitter, for some reason I was trying to run this directly after connecting, obviously there were no auth tokens so it wouldn't authenticate.
Silly me.