client is unauthorized to retrieve access tokens using this method service account error












1















It's been such a major headache getting my service account to authenticate on the same webapp where I have users logging in via oauth2 as well.



So I'm wondering, is this even possible?



If not, should one just stick with the service account? Does one have to then authenticate the users on one's own - old school style? Haha



Thanks.



Regarding the service account, I have enabled the domain wide delegation, enabled the client key + api scope in my G suite admin console, and have gotten the php sample with the books api working. However any time I try any other api, other than books, I get the error,




client is unauthorized to retrieve access tokens using this method




UPDATE: I've tried to use @dalmto's example, and have added a few lines to test the gmail api, for example:



putenv('GOOGLE_APPLICATION_CREDENTIALS=credentials.json');

$user = 'email@domain.de';

function getGoogleClient() {
return getServiceAccountClient();
}

function getServiceAccountClient() {
try {
// Create and configure a new client object.
$client2 = new Google_Client();
$client2->useApplicationDefaultCredentials();
$client2->setScopes(array('https://www.googleapis.com/auth/userinfo.email','https://www.googleapis.com/auth/admin.directory.user.readonly','https://www.googleapis.com/auth/userinfo.profile','https://www.googleapis.com/auth/gmail.readonly','https://www.googleapis.com/auth/calendar'));
$client2->setAccessType('offline');
$client2->setSubject($user);
return $client2;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}

$newGoogleClient = getGoogleClient();

$service3 = new Google_Service_Gmail($newGoogleClient);
$results3 = $service3->users_labels->listUsersLabels($user);


But am now just receiving "400: Bad Request" errors



EDIT: After some more digging there is a note: 'failedPrecondition' - any idea which precondition that could be? I've allowed the following scopes for the client in my admin console:




hxxps://www.googleapis.com/auth/gmail.metadata,
hxxps://www.googleapis.com/auth/userinfo.email,
hxxps://www.googleapis.com/auth/userinfo.profile,
hxxps://www.googleapis.com/auth/gmail.modify,
hxxps://www.googleapis.com/auth/gmail.readonly,

hxxps://www.googleapis.com/auth/gmail.labels,

hxxps://mail.google.com/




And enabled the apis and enabled the scope in the 'OAuth Consent Screen'



DWD is also enabled: Service Account Overview Screenshot



EDIT2: Okay so I found the missing precondition was the "setSubject".



Once I added that it went a step further, but still failed again at '"error": "unauthorized_client",n "error_description": "Client is unauthorized to retrieve access tokens using this method.'



FYI: When creating the service account, I gave it the "project -> owner" role. Is that sufficient? Does one have to add more?



EDIT3: I've also just checked logger and it says that DWD is enabled.. Im at my whits end here haha



   client: {
adminState: {
updateTime: "2018-11-23T00:29:44.810Z"
}
assertionMatchExistingGrant: "MATCH_GRANT_DISABLED"
authType: "PUBLIC_KEY"
brandId: "aaaaaaaaaaaaaa"
clientId: "aaaaaaaaaaaaaaaaaa"
consistencyToken: "2018-11-23T00:29:44.953175Z"
creationTime: "2018-11-23T00:29:44.810Z"
displayName: "Client for servicemaint1"
domainWideDelegation: "DELEGATION_ENABLED"
projectNumber: "aaaaaaaaaaaaaaaa"
threeLeggedOauth: "DISABLED"
updateTime: "2018-11-23T00:29:44.953175Z"
}


EDIT4: FINALLY WORKING!



So I had been trying this in a new project I created for testing all morning / last night. But my oauth2 user authenticating was running through a different project (where I also couldn't get the service account working all of yesterday morning / afternoon).



So anyway, I noticed in: https://myaccount.google.com/permissions "Apps with Access to your account" - only my old project / app was authorized. So I switched back to my first project, created a new service account client ID .json file and it finallyyy worked to authenticate both! :)



I must have that authorized that somewhere extra along the line which I had not done with the second project.



Thanks again.



EDIT5: One more quick question - is this the correct way to do this on stackoverflow? With constantly going back to edit?



Also for others stumbling upon this later, here's my total authentication block (sorry its a bit long):



putenv('GOOGLE_APPLICATION_CREDENTIALS=maintenanceapp.json');

$user = 'xyz@abc.com';

function getGoogleClient() {
return getServiceAccountClient();
}

function getServiceAccountClient() {
$user = 'xyz@abc.com';
try {
// Create and configure a new client object.
$client2 = new Google_Client();
$client2->useApplicationDefaultCredentials();
$client2->setScopes(['https://www.googleapis.com/auth/gmail.metadata','https://www.googleapis.com/auth/userinfo.email','https://www.googleapis.com/auth/userinfo.profile','https://www.googleapis.com/auth/gmail.modify','https://www.googleapis.com/auth/gmail.readonly','https://www.googleapis.com/auth/gmail.labels']);
//$client2->setAccessType('offline');
$client2->setSubject($user);
return $client2;
} catch (Exception $e) {
echo "An error occurred: " . $e->getMessage();
}
}

$newGoogleClient = getGoogleClient();

$service3 = new Google_Service_Gmail($newGoogleClient);
$results3 = $service3->users_labels->listUsersLabels($user);


/*************************************************
* Ensure you've downloaded your oauth credentials
************************************************/
if (!$oauth_credentials = getOAuthCredentialsFile()) {
echo missingOAuth2CredentialsWarning();
return;
}
/************************************************
* NOTICE:
* The redirect URI is to the current page, e.g:
* http://localhost:8080/idtoken.php
************************************************/
$redirect_uri = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
$client = new Google_Client();
// USER AUTH
$client->setAuthConfig($oauth_credentials);
$client->setRedirectUri($redirect_uri);
$client->setScopes(array('https://www.googleapis.com/auth/userinfo.email','https://www.googleapis.com/auth/userinfo.profile','https://www.googleapis.com/auth/gmail.readonly','https://www.googleapis.com/auth/calendar'));
$client->setApprovalPrompt('auto');
$client->setAccessType('offline');
$plus = new Google_Service_Plus($client);

/************************************************
* If we're logging out we just need to clear our
* local access token in this case
************************************************/
if (isset($_REQUEST['logout'])) {
unset($_SESSION['id_token_token']);
}

/************************************************
* If we have a code back from the OAuth 2.0 flow,
* we need to exchange that with the
* Google_Client::fetchAccessTokenWithAuthCode()
* function. We store the resultant access token
* bundle in the session, and redirect to ourself.
************************************************/
if (isset($_GET['code'])) {
$token = $client->fetchAccessTokenWithAuthCode($_GET['code']);
// store in the session also
$_SESSION['id_token_token'] = $token;
// redirect back to the example
header('Location: https://abc.de/index.php');
// return;
}
/************************************************
If we have an access token, we can make
requests, else we generate an authentication URL.
************************************************/
if (
!empty($_SESSION['id_token_token'])
&& isset($_SESSION['id_token_token']['id_token'])
) {
$client->setAccessToken($_SESSION['id_token_token']);
} else {
$authUrl = $client->createAuthUrl();
//header('Location: ' . $authUrl);
}
/************************************************
If we're signed in we can go ahead and retrieve
the ID token, which is part of the bundle of
data that is exchange in the authenticate step
- we only need to do a network call if we have
to retrieve the Google certificate to verify it,
and that can be cached.
************************************************/
if ($client->getAccessToken()) {
$token_data = $client->verifyIdToken();
}









share|improve this question

























  • This is a good question-answer. We need more questions like yours with lots of real-world details.

    – John Hanley
    Nov 26 '18 at 1:06
















1















It's been such a major headache getting my service account to authenticate on the same webapp where I have users logging in via oauth2 as well.



So I'm wondering, is this even possible?



If not, should one just stick with the service account? Does one have to then authenticate the users on one's own - old school style? Haha



Thanks.



Regarding the service account, I have enabled the domain wide delegation, enabled the client key + api scope in my G suite admin console, and have gotten the php sample with the books api working. However any time I try any other api, other than books, I get the error,




client is unauthorized to retrieve access tokens using this method




UPDATE: I've tried to use @dalmto's example, and have added a few lines to test the gmail api, for example:



putenv('GOOGLE_APPLICATION_CREDENTIALS=credentials.json');

$user = 'email@domain.de';

function getGoogleClient() {
return getServiceAccountClient();
}

function getServiceAccountClient() {
try {
// Create and configure a new client object.
$client2 = new Google_Client();
$client2->useApplicationDefaultCredentials();
$client2->setScopes(array('https://www.googleapis.com/auth/userinfo.email','https://www.googleapis.com/auth/admin.directory.user.readonly','https://www.googleapis.com/auth/userinfo.profile','https://www.googleapis.com/auth/gmail.readonly','https://www.googleapis.com/auth/calendar'));
$client2->setAccessType('offline');
$client2->setSubject($user);
return $client2;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}

$newGoogleClient = getGoogleClient();

$service3 = new Google_Service_Gmail($newGoogleClient);
$results3 = $service3->users_labels->listUsersLabels($user);


But am now just receiving "400: Bad Request" errors



EDIT: After some more digging there is a note: 'failedPrecondition' - any idea which precondition that could be? I've allowed the following scopes for the client in my admin console:




hxxps://www.googleapis.com/auth/gmail.metadata,
hxxps://www.googleapis.com/auth/userinfo.email,
hxxps://www.googleapis.com/auth/userinfo.profile,
hxxps://www.googleapis.com/auth/gmail.modify,
hxxps://www.googleapis.com/auth/gmail.readonly,

hxxps://www.googleapis.com/auth/gmail.labels,

hxxps://mail.google.com/




And enabled the apis and enabled the scope in the 'OAuth Consent Screen'



DWD is also enabled: Service Account Overview Screenshot



EDIT2: Okay so I found the missing precondition was the "setSubject".



Once I added that it went a step further, but still failed again at '"error": "unauthorized_client",n "error_description": "Client is unauthorized to retrieve access tokens using this method.'



FYI: When creating the service account, I gave it the "project -> owner" role. Is that sufficient? Does one have to add more?



EDIT3: I've also just checked logger and it says that DWD is enabled.. Im at my whits end here haha



   client: {
adminState: {
updateTime: "2018-11-23T00:29:44.810Z"
}
assertionMatchExistingGrant: "MATCH_GRANT_DISABLED"
authType: "PUBLIC_KEY"
brandId: "aaaaaaaaaaaaaa"
clientId: "aaaaaaaaaaaaaaaaaa"
consistencyToken: "2018-11-23T00:29:44.953175Z"
creationTime: "2018-11-23T00:29:44.810Z"
displayName: "Client for servicemaint1"
domainWideDelegation: "DELEGATION_ENABLED"
projectNumber: "aaaaaaaaaaaaaaaa"
threeLeggedOauth: "DISABLED"
updateTime: "2018-11-23T00:29:44.953175Z"
}


EDIT4: FINALLY WORKING!



So I had been trying this in a new project I created for testing all morning / last night. But my oauth2 user authenticating was running through a different project (where I also couldn't get the service account working all of yesterday morning / afternoon).



So anyway, I noticed in: https://myaccount.google.com/permissions "Apps with Access to your account" - only my old project / app was authorized. So I switched back to my first project, created a new service account client ID .json file and it finallyyy worked to authenticate both! :)



I must have that authorized that somewhere extra along the line which I had not done with the second project.



Thanks again.



EDIT5: One more quick question - is this the correct way to do this on stackoverflow? With constantly going back to edit?



Also for others stumbling upon this later, here's my total authentication block (sorry its a bit long):



putenv('GOOGLE_APPLICATION_CREDENTIALS=maintenanceapp.json');

$user = 'xyz@abc.com';

function getGoogleClient() {
return getServiceAccountClient();
}

function getServiceAccountClient() {
$user = 'xyz@abc.com';
try {
// Create and configure a new client object.
$client2 = new Google_Client();
$client2->useApplicationDefaultCredentials();
$client2->setScopes(['https://www.googleapis.com/auth/gmail.metadata','https://www.googleapis.com/auth/userinfo.email','https://www.googleapis.com/auth/userinfo.profile','https://www.googleapis.com/auth/gmail.modify','https://www.googleapis.com/auth/gmail.readonly','https://www.googleapis.com/auth/gmail.labels']);
//$client2->setAccessType('offline');
$client2->setSubject($user);
return $client2;
} catch (Exception $e) {
echo "An error occurred: " . $e->getMessage();
}
}

$newGoogleClient = getGoogleClient();

$service3 = new Google_Service_Gmail($newGoogleClient);
$results3 = $service3->users_labels->listUsersLabels($user);


/*************************************************
* Ensure you've downloaded your oauth credentials
************************************************/
if (!$oauth_credentials = getOAuthCredentialsFile()) {
echo missingOAuth2CredentialsWarning();
return;
}
/************************************************
* NOTICE:
* The redirect URI is to the current page, e.g:
* http://localhost:8080/idtoken.php
************************************************/
$redirect_uri = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
$client = new Google_Client();
// USER AUTH
$client->setAuthConfig($oauth_credentials);
$client->setRedirectUri($redirect_uri);
$client->setScopes(array('https://www.googleapis.com/auth/userinfo.email','https://www.googleapis.com/auth/userinfo.profile','https://www.googleapis.com/auth/gmail.readonly','https://www.googleapis.com/auth/calendar'));
$client->setApprovalPrompt('auto');
$client->setAccessType('offline');
$plus = new Google_Service_Plus($client);

/************************************************
* If we're logging out we just need to clear our
* local access token in this case
************************************************/
if (isset($_REQUEST['logout'])) {
unset($_SESSION['id_token_token']);
}

/************************************************
* If we have a code back from the OAuth 2.0 flow,
* we need to exchange that with the
* Google_Client::fetchAccessTokenWithAuthCode()
* function. We store the resultant access token
* bundle in the session, and redirect to ourself.
************************************************/
if (isset($_GET['code'])) {
$token = $client->fetchAccessTokenWithAuthCode($_GET['code']);
// store in the session also
$_SESSION['id_token_token'] = $token;
// redirect back to the example
header('Location: https://abc.de/index.php');
// return;
}
/************************************************
If we have an access token, we can make
requests, else we generate an authentication URL.
************************************************/
if (
!empty($_SESSION['id_token_token'])
&& isset($_SESSION['id_token_token']['id_token'])
) {
$client->setAccessToken($_SESSION['id_token_token']);
} else {
$authUrl = $client->createAuthUrl();
//header('Location: ' . $authUrl);
}
/************************************************
If we're signed in we can go ahead and retrieve
the ID token, which is part of the bundle of
data that is exchange in the authenticate step
- we only need to do a network call if we have
to retrieve the Google certificate to verify it,
and that can be cached.
************************************************/
if ($client->getAccessToken()) {
$token_data = $client->verifyIdToken();
}









share|improve this question

























  • This is a good question-answer. We need more questions like yours with lots of real-world details.

    – John Hanley
    Nov 26 '18 at 1:06














1












1








1


1






It's been such a major headache getting my service account to authenticate on the same webapp where I have users logging in via oauth2 as well.



So I'm wondering, is this even possible?



If not, should one just stick with the service account? Does one have to then authenticate the users on one's own - old school style? Haha



Thanks.



Regarding the service account, I have enabled the domain wide delegation, enabled the client key + api scope in my G suite admin console, and have gotten the php sample with the books api working. However any time I try any other api, other than books, I get the error,




client is unauthorized to retrieve access tokens using this method




UPDATE: I've tried to use @dalmto's example, and have added a few lines to test the gmail api, for example:



putenv('GOOGLE_APPLICATION_CREDENTIALS=credentials.json');

$user = 'email@domain.de';

function getGoogleClient() {
return getServiceAccountClient();
}

function getServiceAccountClient() {
try {
// Create and configure a new client object.
$client2 = new Google_Client();
$client2->useApplicationDefaultCredentials();
$client2->setScopes(array('https://www.googleapis.com/auth/userinfo.email','https://www.googleapis.com/auth/admin.directory.user.readonly','https://www.googleapis.com/auth/userinfo.profile','https://www.googleapis.com/auth/gmail.readonly','https://www.googleapis.com/auth/calendar'));
$client2->setAccessType('offline');
$client2->setSubject($user);
return $client2;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}

$newGoogleClient = getGoogleClient();

$service3 = new Google_Service_Gmail($newGoogleClient);
$results3 = $service3->users_labels->listUsersLabels($user);


But am now just receiving "400: Bad Request" errors



EDIT: After some more digging there is a note: 'failedPrecondition' - any idea which precondition that could be? I've allowed the following scopes for the client in my admin console:




hxxps://www.googleapis.com/auth/gmail.metadata,
hxxps://www.googleapis.com/auth/userinfo.email,
hxxps://www.googleapis.com/auth/userinfo.profile,
hxxps://www.googleapis.com/auth/gmail.modify,
hxxps://www.googleapis.com/auth/gmail.readonly,

hxxps://www.googleapis.com/auth/gmail.labels,

hxxps://mail.google.com/




And enabled the apis and enabled the scope in the 'OAuth Consent Screen'



DWD is also enabled: Service Account Overview Screenshot



EDIT2: Okay so I found the missing precondition was the "setSubject".



Once I added that it went a step further, but still failed again at '"error": "unauthorized_client",n "error_description": "Client is unauthorized to retrieve access tokens using this method.'



FYI: When creating the service account, I gave it the "project -> owner" role. Is that sufficient? Does one have to add more?



EDIT3: I've also just checked logger and it says that DWD is enabled.. Im at my whits end here haha



   client: {
adminState: {
updateTime: "2018-11-23T00:29:44.810Z"
}
assertionMatchExistingGrant: "MATCH_GRANT_DISABLED"
authType: "PUBLIC_KEY"
brandId: "aaaaaaaaaaaaaa"
clientId: "aaaaaaaaaaaaaaaaaa"
consistencyToken: "2018-11-23T00:29:44.953175Z"
creationTime: "2018-11-23T00:29:44.810Z"
displayName: "Client for servicemaint1"
domainWideDelegation: "DELEGATION_ENABLED"
projectNumber: "aaaaaaaaaaaaaaaa"
threeLeggedOauth: "DISABLED"
updateTime: "2018-11-23T00:29:44.953175Z"
}


EDIT4: FINALLY WORKING!



So I had been trying this in a new project I created for testing all morning / last night. But my oauth2 user authenticating was running through a different project (where I also couldn't get the service account working all of yesterday morning / afternoon).



So anyway, I noticed in: https://myaccount.google.com/permissions "Apps with Access to your account" - only my old project / app was authorized. So I switched back to my first project, created a new service account client ID .json file and it finallyyy worked to authenticate both! :)



I must have that authorized that somewhere extra along the line which I had not done with the second project.



Thanks again.



EDIT5: One more quick question - is this the correct way to do this on stackoverflow? With constantly going back to edit?



Also for others stumbling upon this later, here's my total authentication block (sorry its a bit long):



putenv('GOOGLE_APPLICATION_CREDENTIALS=maintenanceapp.json');

$user = 'xyz@abc.com';

function getGoogleClient() {
return getServiceAccountClient();
}

function getServiceAccountClient() {
$user = 'xyz@abc.com';
try {
// Create and configure a new client object.
$client2 = new Google_Client();
$client2->useApplicationDefaultCredentials();
$client2->setScopes(['https://www.googleapis.com/auth/gmail.metadata','https://www.googleapis.com/auth/userinfo.email','https://www.googleapis.com/auth/userinfo.profile','https://www.googleapis.com/auth/gmail.modify','https://www.googleapis.com/auth/gmail.readonly','https://www.googleapis.com/auth/gmail.labels']);
//$client2->setAccessType('offline');
$client2->setSubject($user);
return $client2;
} catch (Exception $e) {
echo "An error occurred: " . $e->getMessage();
}
}

$newGoogleClient = getGoogleClient();

$service3 = new Google_Service_Gmail($newGoogleClient);
$results3 = $service3->users_labels->listUsersLabels($user);


/*************************************************
* Ensure you've downloaded your oauth credentials
************************************************/
if (!$oauth_credentials = getOAuthCredentialsFile()) {
echo missingOAuth2CredentialsWarning();
return;
}
/************************************************
* NOTICE:
* The redirect URI is to the current page, e.g:
* http://localhost:8080/idtoken.php
************************************************/
$redirect_uri = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
$client = new Google_Client();
// USER AUTH
$client->setAuthConfig($oauth_credentials);
$client->setRedirectUri($redirect_uri);
$client->setScopes(array('https://www.googleapis.com/auth/userinfo.email','https://www.googleapis.com/auth/userinfo.profile','https://www.googleapis.com/auth/gmail.readonly','https://www.googleapis.com/auth/calendar'));
$client->setApprovalPrompt('auto');
$client->setAccessType('offline');
$plus = new Google_Service_Plus($client);

/************************************************
* If we're logging out we just need to clear our
* local access token in this case
************************************************/
if (isset($_REQUEST['logout'])) {
unset($_SESSION['id_token_token']);
}

/************************************************
* If we have a code back from the OAuth 2.0 flow,
* we need to exchange that with the
* Google_Client::fetchAccessTokenWithAuthCode()
* function. We store the resultant access token
* bundle in the session, and redirect to ourself.
************************************************/
if (isset($_GET['code'])) {
$token = $client->fetchAccessTokenWithAuthCode($_GET['code']);
// store in the session also
$_SESSION['id_token_token'] = $token;
// redirect back to the example
header('Location: https://abc.de/index.php');
// return;
}
/************************************************
If we have an access token, we can make
requests, else we generate an authentication URL.
************************************************/
if (
!empty($_SESSION['id_token_token'])
&& isset($_SESSION['id_token_token']['id_token'])
) {
$client->setAccessToken($_SESSION['id_token_token']);
} else {
$authUrl = $client->createAuthUrl();
//header('Location: ' . $authUrl);
}
/************************************************
If we're signed in we can go ahead and retrieve
the ID token, which is part of the bundle of
data that is exchange in the authenticate step
- we only need to do a network call if we have
to retrieve the Google certificate to verify it,
and that can be cached.
************************************************/
if ($client->getAccessToken()) {
$token_data = $client->verifyIdToken();
}









share|improve this question
















It's been such a major headache getting my service account to authenticate on the same webapp where I have users logging in via oauth2 as well.



So I'm wondering, is this even possible?



If not, should one just stick with the service account? Does one have to then authenticate the users on one's own - old school style? Haha



Thanks.



Regarding the service account, I have enabled the domain wide delegation, enabled the client key + api scope in my G suite admin console, and have gotten the php sample with the books api working. However any time I try any other api, other than books, I get the error,




client is unauthorized to retrieve access tokens using this method




UPDATE: I've tried to use @dalmto's example, and have added a few lines to test the gmail api, for example:



putenv('GOOGLE_APPLICATION_CREDENTIALS=credentials.json');

$user = 'email@domain.de';

function getGoogleClient() {
return getServiceAccountClient();
}

function getServiceAccountClient() {
try {
// Create and configure a new client object.
$client2 = new Google_Client();
$client2->useApplicationDefaultCredentials();
$client2->setScopes(array('https://www.googleapis.com/auth/userinfo.email','https://www.googleapis.com/auth/admin.directory.user.readonly','https://www.googleapis.com/auth/userinfo.profile','https://www.googleapis.com/auth/gmail.readonly','https://www.googleapis.com/auth/calendar'));
$client2->setAccessType('offline');
$client2->setSubject($user);
return $client2;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}

$newGoogleClient = getGoogleClient();

$service3 = new Google_Service_Gmail($newGoogleClient);
$results3 = $service3->users_labels->listUsersLabels($user);


But am now just receiving "400: Bad Request" errors



EDIT: After some more digging there is a note: 'failedPrecondition' - any idea which precondition that could be? I've allowed the following scopes for the client in my admin console:




hxxps://www.googleapis.com/auth/gmail.metadata,
hxxps://www.googleapis.com/auth/userinfo.email,
hxxps://www.googleapis.com/auth/userinfo.profile,
hxxps://www.googleapis.com/auth/gmail.modify,
hxxps://www.googleapis.com/auth/gmail.readonly,

hxxps://www.googleapis.com/auth/gmail.labels,

hxxps://mail.google.com/




And enabled the apis and enabled the scope in the 'OAuth Consent Screen'



DWD is also enabled: Service Account Overview Screenshot



EDIT2: Okay so I found the missing precondition was the "setSubject".



Once I added that it went a step further, but still failed again at '"error": "unauthorized_client",n "error_description": "Client is unauthorized to retrieve access tokens using this method.'



FYI: When creating the service account, I gave it the "project -> owner" role. Is that sufficient? Does one have to add more?



EDIT3: I've also just checked logger and it says that DWD is enabled.. Im at my whits end here haha



   client: {
adminState: {
updateTime: "2018-11-23T00:29:44.810Z"
}
assertionMatchExistingGrant: "MATCH_GRANT_DISABLED"
authType: "PUBLIC_KEY"
brandId: "aaaaaaaaaaaaaa"
clientId: "aaaaaaaaaaaaaaaaaa"
consistencyToken: "2018-11-23T00:29:44.953175Z"
creationTime: "2018-11-23T00:29:44.810Z"
displayName: "Client for servicemaint1"
domainWideDelegation: "DELEGATION_ENABLED"
projectNumber: "aaaaaaaaaaaaaaaa"
threeLeggedOauth: "DISABLED"
updateTime: "2018-11-23T00:29:44.953175Z"
}


EDIT4: FINALLY WORKING!



So I had been trying this in a new project I created for testing all morning / last night. But my oauth2 user authenticating was running through a different project (where I also couldn't get the service account working all of yesterday morning / afternoon).



So anyway, I noticed in: https://myaccount.google.com/permissions "Apps with Access to your account" - only my old project / app was authorized. So I switched back to my first project, created a new service account client ID .json file and it finallyyy worked to authenticate both! :)



I must have that authorized that somewhere extra along the line which I had not done with the second project.



Thanks again.



EDIT5: One more quick question - is this the correct way to do this on stackoverflow? With constantly going back to edit?



Also for others stumbling upon this later, here's my total authentication block (sorry its a bit long):



putenv('GOOGLE_APPLICATION_CREDENTIALS=maintenanceapp.json');

$user = 'xyz@abc.com';

function getGoogleClient() {
return getServiceAccountClient();
}

function getServiceAccountClient() {
$user = 'xyz@abc.com';
try {
// Create and configure a new client object.
$client2 = new Google_Client();
$client2->useApplicationDefaultCredentials();
$client2->setScopes(['https://www.googleapis.com/auth/gmail.metadata','https://www.googleapis.com/auth/userinfo.email','https://www.googleapis.com/auth/userinfo.profile','https://www.googleapis.com/auth/gmail.modify','https://www.googleapis.com/auth/gmail.readonly','https://www.googleapis.com/auth/gmail.labels']);
//$client2->setAccessType('offline');
$client2->setSubject($user);
return $client2;
} catch (Exception $e) {
echo "An error occurred: " . $e->getMessage();
}
}

$newGoogleClient = getGoogleClient();

$service3 = new Google_Service_Gmail($newGoogleClient);
$results3 = $service3->users_labels->listUsersLabels($user);


/*************************************************
* Ensure you've downloaded your oauth credentials
************************************************/
if (!$oauth_credentials = getOAuthCredentialsFile()) {
echo missingOAuth2CredentialsWarning();
return;
}
/************************************************
* NOTICE:
* The redirect URI is to the current page, e.g:
* http://localhost:8080/idtoken.php
************************************************/
$redirect_uri = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
$client = new Google_Client();
// USER AUTH
$client->setAuthConfig($oauth_credentials);
$client->setRedirectUri($redirect_uri);
$client->setScopes(array('https://www.googleapis.com/auth/userinfo.email','https://www.googleapis.com/auth/userinfo.profile','https://www.googleapis.com/auth/gmail.readonly','https://www.googleapis.com/auth/calendar'));
$client->setApprovalPrompt('auto');
$client->setAccessType('offline');
$plus = new Google_Service_Plus($client);

/************************************************
* If we're logging out we just need to clear our
* local access token in this case
************************************************/
if (isset($_REQUEST['logout'])) {
unset($_SESSION['id_token_token']);
}

/************************************************
* If we have a code back from the OAuth 2.0 flow,
* we need to exchange that with the
* Google_Client::fetchAccessTokenWithAuthCode()
* function. We store the resultant access token
* bundle in the session, and redirect to ourself.
************************************************/
if (isset($_GET['code'])) {
$token = $client->fetchAccessTokenWithAuthCode($_GET['code']);
// store in the session also
$_SESSION['id_token_token'] = $token;
// redirect back to the example
header('Location: https://abc.de/index.php');
// return;
}
/************************************************
If we have an access token, we can make
requests, else we generate an authentication URL.
************************************************/
if (
!empty($_SESSION['id_token_token'])
&& isset($_SESSION['id_token_token']['id_token'])
) {
$client->setAccessToken($_SESSION['id_token_token']);
} else {
$authUrl = $client->createAuthUrl();
//header('Location: ' . $authUrl);
}
/************************************************
If we're signed in we can go ahead and retrieve
the ID token, which is part of the bundle of
data that is exchange in the authenticate step
- we only need to do a network call if we have
to retrieve the Google certificate to verify it,
and that can be cached.
************************************************/
if ($client->getAccessToken()) {
$token_data = $client->verifyIdToken();
}






php google-oauth gmail-api service-accounts gsuite






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 23 '18 at 10:06







ndom91

















asked Nov 23 '18 at 6:44









ndom91ndom91

3118




3118













  • This is a good question-answer. We need more questions like yours with lots of real-world details.

    – John Hanley
    Nov 26 '18 at 1:06



















  • This is a good question-answer. We need more questions like yours with lots of real-world details.

    – John Hanley
    Nov 26 '18 at 1:06

















This is a good question-answer. We need more questions like yours with lots of real-world details.

– John Hanley
Nov 26 '18 at 1:06





This is a good question-answer. We need more questions like yours with lots of real-world details.

– John Hanley
Nov 26 '18 at 1:06












2 Answers
2






active

oldest

votes


















0














In google developer console when you create your project and the credentials you must choose which type of client you are going to create for which type of application.



There are several different ways to authenticate to google.




  • OAuth2 native

  • OAuth2 web

  • Mobile

  • Service account


The code to use these clients is also different. You cant create a web OAuth2 client and use it for the code meant to be calling a service account.




"client is unauthorized to retrieve access tokens using this method".




Means exactly that. The client you have set up on Google developer console is either not a service account client or the code you are using is not meant for a service account client.



This is my serviceaccount.php sample. If your code needs to look something like this and you need to make sure that the client you created on the google developer console is a service account client.



require_once __DIR__ . '/vendor/autoload.php';
// Use the developers console and download your service account
// credentials in JSON format. Place the file in this directory or
// change the key file location if necessary.
putenv('GOOGLE_APPLICATION_CREDENTIALS='.__DIR__.'/service-account.json');
/**
* Gets the Google client refreshing auth if needed.
* Documentation: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
* Initializes a client object.
* @return A google client object.
*/
function getGoogleClient() {
return getServiceAccountClient();
}
/**
* Builds the Google client object.
* Documentation: https://developers.google.com/api-client-library/php/auth/service-accounts
* Scopes will need to be changed depending upon the API's being accessed.
* array(Google_Service_Analytics::ANALYTICS_READONLY, Google_Service_Analytics::ANALYTICS)
* List of Google Scopes: https://developers.google.com/identity/protocols/googlescopes
* @return A google client object.
*/
function getServiceAccountClient() {
try {
// Create and configure a new client object.
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->addScope([YOUR SCOPES HERE]);
return $client;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}


Developer console



Under clients check that the client you are using is one that can be found under service account keys. If not then it is the wrong client type and will not work with your code. Create a new service account client and set up domain wide delegation with that client id.



enter image description here






share|improve this answer


























  • Thanks for the comment, so I've got the regular oauth2 web user authentication working via their example code more or less. Now I am trying to add the service account to it. See my edit above. (is this the correct way to do this on stackoverflow, im still confused as I cant easily add code to comments like this..)

    – ndom91
    Nov 23 '18 at 7:32













  • Okay so I found the missing precondition was the "setSubject". Once I added that it went a step further, but still failed again at '"error": "unauthorized_client",n "error_description": "Client is unauthorized to retrieve access tokens using this method.'

    – ndom91
    Nov 23 '18 at 7:59











  • Then go to google developer console and check that the client you created is a service account client type. If you are using the same code i posted then its not a service account client. Once you have created the proper service account client then download the client json file and use that with your code. Check my update

    – DaImTo
    Nov 23 '18 at 9:19













  • Yes thats what I am using - See screenshot: i.imgur.com/leAMXZB.png I have adjusted your code so that my service account is alwys using $client2 and my oauth2 user authentication is using $client - i just doubel checked that i didnt cross up any variables by accident The json file explicitly says: "type": "service_account", as the first value

    – ndom91
    Nov 23 '18 at 9:52





















0














response_type=code
client_id=348268306866-9dl0kdgn2f9bjhoge7pris1jo8u9si47.apps.googleusercontent.com
redirect_uri=https://degoo.com/me/googleoauth2callback
access_type=offline
scope=https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/contacts.readonly
state={"RedirectUrl":"/me/chooseaccount","RegisterIfNotExists":true}


That’s all we know.






share|improve this answer


























  • can you explain what your code does? it could be much more better also for future users

    – DaFois
    Nov 24 '18 at 18:27











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53441806%2fclient-is-unauthorized-to-retrieve-access-tokens-using-this-method-service-accou%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














In google developer console when you create your project and the credentials you must choose which type of client you are going to create for which type of application.



There are several different ways to authenticate to google.




  • OAuth2 native

  • OAuth2 web

  • Mobile

  • Service account


The code to use these clients is also different. You cant create a web OAuth2 client and use it for the code meant to be calling a service account.




"client is unauthorized to retrieve access tokens using this method".




Means exactly that. The client you have set up on Google developer console is either not a service account client or the code you are using is not meant for a service account client.



This is my serviceaccount.php sample. If your code needs to look something like this and you need to make sure that the client you created on the google developer console is a service account client.



require_once __DIR__ . '/vendor/autoload.php';
// Use the developers console and download your service account
// credentials in JSON format. Place the file in this directory or
// change the key file location if necessary.
putenv('GOOGLE_APPLICATION_CREDENTIALS='.__DIR__.'/service-account.json');
/**
* Gets the Google client refreshing auth if needed.
* Documentation: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
* Initializes a client object.
* @return A google client object.
*/
function getGoogleClient() {
return getServiceAccountClient();
}
/**
* Builds the Google client object.
* Documentation: https://developers.google.com/api-client-library/php/auth/service-accounts
* Scopes will need to be changed depending upon the API's being accessed.
* array(Google_Service_Analytics::ANALYTICS_READONLY, Google_Service_Analytics::ANALYTICS)
* List of Google Scopes: https://developers.google.com/identity/protocols/googlescopes
* @return A google client object.
*/
function getServiceAccountClient() {
try {
// Create and configure a new client object.
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->addScope([YOUR SCOPES HERE]);
return $client;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}


Developer console



Under clients check that the client you are using is one that can be found under service account keys. If not then it is the wrong client type and will not work with your code. Create a new service account client and set up domain wide delegation with that client id.



enter image description here






share|improve this answer


























  • Thanks for the comment, so I've got the regular oauth2 web user authentication working via their example code more or less. Now I am trying to add the service account to it. See my edit above. (is this the correct way to do this on stackoverflow, im still confused as I cant easily add code to comments like this..)

    – ndom91
    Nov 23 '18 at 7:32













  • Okay so I found the missing precondition was the "setSubject". Once I added that it went a step further, but still failed again at '"error": "unauthorized_client",n "error_description": "Client is unauthorized to retrieve access tokens using this method.'

    – ndom91
    Nov 23 '18 at 7:59











  • Then go to google developer console and check that the client you created is a service account client type. If you are using the same code i posted then its not a service account client. Once you have created the proper service account client then download the client json file and use that with your code. Check my update

    – DaImTo
    Nov 23 '18 at 9:19













  • Yes thats what I am using - See screenshot: i.imgur.com/leAMXZB.png I have adjusted your code so that my service account is alwys using $client2 and my oauth2 user authentication is using $client - i just doubel checked that i didnt cross up any variables by accident The json file explicitly says: "type": "service_account", as the first value

    – ndom91
    Nov 23 '18 at 9:52


















0














In google developer console when you create your project and the credentials you must choose which type of client you are going to create for which type of application.



There are several different ways to authenticate to google.




  • OAuth2 native

  • OAuth2 web

  • Mobile

  • Service account


The code to use these clients is also different. You cant create a web OAuth2 client and use it for the code meant to be calling a service account.




"client is unauthorized to retrieve access tokens using this method".




Means exactly that. The client you have set up on Google developer console is either not a service account client or the code you are using is not meant for a service account client.



This is my serviceaccount.php sample. If your code needs to look something like this and you need to make sure that the client you created on the google developer console is a service account client.



require_once __DIR__ . '/vendor/autoload.php';
// Use the developers console and download your service account
// credentials in JSON format. Place the file in this directory or
// change the key file location if necessary.
putenv('GOOGLE_APPLICATION_CREDENTIALS='.__DIR__.'/service-account.json');
/**
* Gets the Google client refreshing auth if needed.
* Documentation: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
* Initializes a client object.
* @return A google client object.
*/
function getGoogleClient() {
return getServiceAccountClient();
}
/**
* Builds the Google client object.
* Documentation: https://developers.google.com/api-client-library/php/auth/service-accounts
* Scopes will need to be changed depending upon the API's being accessed.
* array(Google_Service_Analytics::ANALYTICS_READONLY, Google_Service_Analytics::ANALYTICS)
* List of Google Scopes: https://developers.google.com/identity/protocols/googlescopes
* @return A google client object.
*/
function getServiceAccountClient() {
try {
// Create and configure a new client object.
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->addScope([YOUR SCOPES HERE]);
return $client;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}


Developer console



Under clients check that the client you are using is one that can be found under service account keys. If not then it is the wrong client type and will not work with your code. Create a new service account client and set up domain wide delegation with that client id.



enter image description here






share|improve this answer


























  • Thanks for the comment, so I've got the regular oauth2 web user authentication working via their example code more or less. Now I am trying to add the service account to it. See my edit above. (is this the correct way to do this on stackoverflow, im still confused as I cant easily add code to comments like this..)

    – ndom91
    Nov 23 '18 at 7:32













  • Okay so I found the missing precondition was the "setSubject". Once I added that it went a step further, but still failed again at '"error": "unauthorized_client",n "error_description": "Client is unauthorized to retrieve access tokens using this method.'

    – ndom91
    Nov 23 '18 at 7:59











  • Then go to google developer console and check that the client you created is a service account client type. If you are using the same code i posted then its not a service account client. Once you have created the proper service account client then download the client json file and use that with your code. Check my update

    – DaImTo
    Nov 23 '18 at 9:19













  • Yes thats what I am using - See screenshot: i.imgur.com/leAMXZB.png I have adjusted your code so that my service account is alwys using $client2 and my oauth2 user authentication is using $client - i just doubel checked that i didnt cross up any variables by accident The json file explicitly says: "type": "service_account", as the first value

    – ndom91
    Nov 23 '18 at 9:52
















0












0








0







In google developer console when you create your project and the credentials you must choose which type of client you are going to create for which type of application.



There are several different ways to authenticate to google.




  • OAuth2 native

  • OAuth2 web

  • Mobile

  • Service account


The code to use these clients is also different. You cant create a web OAuth2 client and use it for the code meant to be calling a service account.




"client is unauthorized to retrieve access tokens using this method".




Means exactly that. The client you have set up on Google developer console is either not a service account client or the code you are using is not meant for a service account client.



This is my serviceaccount.php sample. If your code needs to look something like this and you need to make sure that the client you created on the google developer console is a service account client.



require_once __DIR__ . '/vendor/autoload.php';
// Use the developers console and download your service account
// credentials in JSON format. Place the file in this directory or
// change the key file location if necessary.
putenv('GOOGLE_APPLICATION_CREDENTIALS='.__DIR__.'/service-account.json');
/**
* Gets the Google client refreshing auth if needed.
* Documentation: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
* Initializes a client object.
* @return A google client object.
*/
function getGoogleClient() {
return getServiceAccountClient();
}
/**
* Builds the Google client object.
* Documentation: https://developers.google.com/api-client-library/php/auth/service-accounts
* Scopes will need to be changed depending upon the API's being accessed.
* array(Google_Service_Analytics::ANALYTICS_READONLY, Google_Service_Analytics::ANALYTICS)
* List of Google Scopes: https://developers.google.com/identity/protocols/googlescopes
* @return A google client object.
*/
function getServiceAccountClient() {
try {
// Create and configure a new client object.
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->addScope([YOUR SCOPES HERE]);
return $client;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}


Developer console



Under clients check that the client you are using is one that can be found under service account keys. If not then it is the wrong client type and will not work with your code. Create a new service account client and set up domain wide delegation with that client id.



enter image description here






share|improve this answer















In google developer console when you create your project and the credentials you must choose which type of client you are going to create for which type of application.



There are several different ways to authenticate to google.




  • OAuth2 native

  • OAuth2 web

  • Mobile

  • Service account


The code to use these clients is also different. You cant create a web OAuth2 client and use it for the code meant to be calling a service account.




"client is unauthorized to retrieve access tokens using this method".




Means exactly that. The client you have set up on Google developer console is either not a service account client or the code you are using is not meant for a service account client.



This is my serviceaccount.php sample. If your code needs to look something like this and you need to make sure that the client you created on the google developer console is a service account client.



require_once __DIR__ . '/vendor/autoload.php';
// Use the developers console and download your service account
// credentials in JSON format. Place the file in this directory or
// change the key file location if necessary.
putenv('GOOGLE_APPLICATION_CREDENTIALS='.__DIR__.'/service-account.json');
/**
* Gets the Google client refreshing auth if needed.
* Documentation: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
* Initializes a client object.
* @return A google client object.
*/
function getGoogleClient() {
return getServiceAccountClient();
}
/**
* Builds the Google client object.
* Documentation: https://developers.google.com/api-client-library/php/auth/service-accounts
* Scopes will need to be changed depending upon the API's being accessed.
* array(Google_Service_Analytics::ANALYTICS_READONLY, Google_Service_Analytics::ANALYTICS)
* List of Google Scopes: https://developers.google.com/identity/protocols/googlescopes
* @return A google client object.
*/
function getServiceAccountClient() {
try {
// Create and configure a new client object.
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->addScope([YOUR SCOPES HERE]);
return $client;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}


Developer console



Under clients check that the client you are using is one that can be found under service account keys. If not then it is the wrong client type and will not work with your code. Create a new service account client and set up domain wide delegation with that client id.



enter image description here







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 23 '18 at 9:22

























answered Nov 23 '18 at 6:58









DaImToDaImTo

46.7k1167246




46.7k1167246













  • Thanks for the comment, so I've got the regular oauth2 web user authentication working via their example code more or less. Now I am trying to add the service account to it. See my edit above. (is this the correct way to do this on stackoverflow, im still confused as I cant easily add code to comments like this..)

    – ndom91
    Nov 23 '18 at 7:32













  • Okay so I found the missing precondition was the "setSubject". Once I added that it went a step further, but still failed again at '"error": "unauthorized_client",n "error_description": "Client is unauthorized to retrieve access tokens using this method.'

    – ndom91
    Nov 23 '18 at 7:59











  • Then go to google developer console and check that the client you created is a service account client type. If you are using the same code i posted then its not a service account client. Once you have created the proper service account client then download the client json file and use that with your code. Check my update

    – DaImTo
    Nov 23 '18 at 9:19













  • Yes thats what I am using - See screenshot: i.imgur.com/leAMXZB.png I have adjusted your code so that my service account is alwys using $client2 and my oauth2 user authentication is using $client - i just doubel checked that i didnt cross up any variables by accident The json file explicitly says: "type": "service_account", as the first value

    – ndom91
    Nov 23 '18 at 9:52





















  • Thanks for the comment, so I've got the regular oauth2 web user authentication working via their example code more or less. Now I am trying to add the service account to it. See my edit above. (is this the correct way to do this on stackoverflow, im still confused as I cant easily add code to comments like this..)

    – ndom91
    Nov 23 '18 at 7:32













  • Okay so I found the missing precondition was the "setSubject". Once I added that it went a step further, but still failed again at '"error": "unauthorized_client",n "error_description": "Client is unauthorized to retrieve access tokens using this method.'

    – ndom91
    Nov 23 '18 at 7:59











  • Then go to google developer console and check that the client you created is a service account client type. If you are using the same code i posted then its not a service account client. Once you have created the proper service account client then download the client json file and use that with your code. Check my update

    – DaImTo
    Nov 23 '18 at 9:19













  • Yes thats what I am using - See screenshot: i.imgur.com/leAMXZB.png I have adjusted your code so that my service account is alwys using $client2 and my oauth2 user authentication is using $client - i just doubel checked that i didnt cross up any variables by accident The json file explicitly says: "type": "service_account", as the first value

    – ndom91
    Nov 23 '18 at 9:52



















Thanks for the comment, so I've got the regular oauth2 web user authentication working via their example code more or less. Now I am trying to add the service account to it. See my edit above. (is this the correct way to do this on stackoverflow, im still confused as I cant easily add code to comments like this..)

– ndom91
Nov 23 '18 at 7:32







Thanks for the comment, so I've got the regular oauth2 web user authentication working via their example code more or less. Now I am trying to add the service account to it. See my edit above. (is this the correct way to do this on stackoverflow, im still confused as I cant easily add code to comments like this..)

– ndom91
Nov 23 '18 at 7:32















Okay so I found the missing precondition was the "setSubject". Once I added that it went a step further, but still failed again at '"error": "unauthorized_client",n "error_description": "Client is unauthorized to retrieve access tokens using this method.'

– ndom91
Nov 23 '18 at 7:59





Okay so I found the missing precondition was the "setSubject". Once I added that it went a step further, but still failed again at '"error": "unauthorized_client",n "error_description": "Client is unauthorized to retrieve access tokens using this method.'

– ndom91
Nov 23 '18 at 7:59













Then go to google developer console and check that the client you created is a service account client type. If you are using the same code i posted then its not a service account client. Once you have created the proper service account client then download the client json file and use that with your code. Check my update

– DaImTo
Nov 23 '18 at 9:19







Then go to google developer console and check that the client you created is a service account client type. If you are using the same code i posted then its not a service account client. Once you have created the proper service account client then download the client json file and use that with your code. Check my update

– DaImTo
Nov 23 '18 at 9:19















Yes thats what I am using - See screenshot: i.imgur.com/leAMXZB.png I have adjusted your code so that my service account is alwys using $client2 and my oauth2 user authentication is using $client - i just doubel checked that i didnt cross up any variables by accident The json file explicitly says: "type": "service_account", as the first value

– ndom91
Nov 23 '18 at 9:52







Yes thats what I am using - See screenshot: i.imgur.com/leAMXZB.png I have adjusted your code so that my service account is alwys using $client2 and my oauth2 user authentication is using $client - i just doubel checked that i didnt cross up any variables by accident The json file explicitly says: "type": "service_account", as the first value

– ndom91
Nov 23 '18 at 9:52















0














response_type=code
client_id=348268306866-9dl0kdgn2f9bjhoge7pris1jo8u9si47.apps.googleusercontent.com
redirect_uri=https://degoo.com/me/googleoauth2callback
access_type=offline
scope=https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/contacts.readonly
state={"RedirectUrl":"/me/chooseaccount","RegisterIfNotExists":true}


That’s all we know.






share|improve this answer


























  • can you explain what your code does? it could be much more better also for future users

    – DaFois
    Nov 24 '18 at 18:27
















0














response_type=code
client_id=348268306866-9dl0kdgn2f9bjhoge7pris1jo8u9si47.apps.googleusercontent.com
redirect_uri=https://degoo.com/me/googleoauth2callback
access_type=offline
scope=https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/contacts.readonly
state={"RedirectUrl":"/me/chooseaccount","RegisterIfNotExists":true}


That’s all we know.






share|improve this answer


























  • can you explain what your code does? it could be much more better also for future users

    – DaFois
    Nov 24 '18 at 18:27














0












0








0







response_type=code
client_id=348268306866-9dl0kdgn2f9bjhoge7pris1jo8u9si47.apps.googleusercontent.com
redirect_uri=https://degoo.com/me/googleoauth2callback
access_type=offline
scope=https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/contacts.readonly
state={"RedirectUrl":"/me/chooseaccount","RegisterIfNotExists":true}


That’s all we know.






share|improve this answer















response_type=code
client_id=348268306866-9dl0kdgn2f9bjhoge7pris1jo8u9si47.apps.googleusercontent.com
redirect_uri=https://degoo.com/me/googleoauth2callback
access_type=offline
scope=https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/contacts.readonly
state={"RedirectUrl":"/me/chooseaccount","RegisterIfNotExists":true}


That’s all we know.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 25 '18 at 10:18









Thielicious

2,1131220




2,1131220










answered Nov 24 '18 at 18:13









ErricklyronneclarkErricklyronneclark

1




1













  • can you explain what your code does? it could be much more better also for future users

    – DaFois
    Nov 24 '18 at 18:27



















  • can you explain what your code does? it could be much more better also for future users

    – DaFois
    Nov 24 '18 at 18:27

















can you explain what your code does? it could be much more better also for future users

– DaFois
Nov 24 '18 at 18:27





can you explain what your code does? it could be much more better also for future users

– DaFois
Nov 24 '18 at 18:27


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53441806%2fclient-is-unauthorized-to-retrieve-access-tokens-using-this-method-service-accou%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

Tangent Lines Diagram Along Smooth Curve

Yusuf al-Mu'taman ibn Hud

Zucchini