Hello,
I've the next code inside a callback url after the google login redirection:
if(isset($_GET['code'])) {
$code = $_GET['code'];
$client = Google::initGoogleObject();
$client->setAccessType("offline");
$client->setApprovalPrompt("force");
$token = $client->fetchAccessTokenWithAuthCode($_GET['code']);
try {
$client->setAccessToken($token);
// store in the session also
$_SESSION['id_token_token'] = $token;
}
catch(InvalidArgumentException $ex) {
$error_message = "InvArgExc: {$ex->getMessage()}";
if(isset($token['error']))
$error_message .= ". Token error: {$token['error']}. Token error descr: {$token['error_description']}";
}
// redirect back to the example
$request_uri = Google::getValidUrl('index.php');
}
I can't call to refreshToken() method due this requires a refresh token and this is just the thing I do not have.
The problem is that the $token var is successfully created, and the result is the next:
array(5) {
["access_token"]=>
string(131) "ya29.GlzNBHHe__3zpeyTEXOXGPd-04KLMqoqHQaKYjZo5rSTAKizVTZb51FaSssfuide5nDc0ueAwrsb0BPMsLlU5Lr9iO0uvPwiIqkrc4TYR1lZ9PA0iu9-JaBvIJxP9A"
["token_type"]=>
string(6) "Bearer"
["expires_in"]=>
int(3596)
["id_token"]=>
string(1230) "eyJhbGciOiJSUzI1NiIsImtpZCI6ImU2YmEyOTY5NTU2NWY3ODQ3OTkwMWNmMzU5ZmQ2ZTliZGJiZDdjY2QifQ.eyJhenAiOiIxMDEwMTEyMTI5OTk1LTN1aHU3cWV1ZnNmMHQ0Nmh2anZiYzlxODdrcGJqcTk5LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiYXVkIjoiMTAxMDExMjEyOTk5NS0zdWh1N3FldWZzZjB0NDZodmp2YmM5cTg3a3BianE5OS5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsInN1YiI6IjEwMTA0OTMyNjI1NzgxNDU3NzcxMCIsImVtYWlsIjoiZHJlcXVlbmFAZHJzZWN1cml0eWFwcC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXRfaGFzaCI6InZXWHBVa2Q1bEdYS0xiTnJxMEVIdFEiLCJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJpYXQiOjE1MDYwMzI1MjMsImV4cCI6MTUwNjAzNjEyMywibmFtZSI6IkRhbmllbCBSZXF1ZW5hIENlcnZhbnRlcyIsInBpY3R1cmUiOiJodHRwczovL2xoNS5nb29nbGV1c2VyY29udGVudC5jb20vLVVZMlNFeV93MjZnL0FBQUFBQUFBQUFJL0FBQUFBQUFBQUFBL0FDbkJlUGF0M0JtTVRKWUZObjZDeFFVUjBpa050NVRabWcvczk2LWMvcGhvdG8uanBnIiwiZ2l2ZW5fbmFtZSI6IkRhbmllbCIsImZhbWlseV9uYW1lIjoiUmVxdWVuYSBDZXJ2YW50ZXMiLCJsb2NhbGUiOiJlbi1HQiJ9.glp71vhgahyVYA1uK_3de5Jd4_uVJNp79uXisIRLJhZrJ0rCe2rzfY4rns00a49YZmzCPBShkLxoF1ZwjcMYlvGhHNXN1dKEcDjDn1VvnYhGhNLlGidR31SKLvNwN5yWcEKSIeJjMlHyTh2h62SFBRCW3TGQmnzYQngNKn0WddoNUbBBwXtwWdn_ZUynwmCCv8kMqPwLsbui4zvIZp5eGWV0UsXjv1A3bljooqRwUIlqfU9hR1ACMI_vxhxLk18FhelRLg--d6hh_ZX-fOUQ1zHOAJSzhS6eHugxbbtoE_ZXdhN25in3IZbw0FSetQiidwBo55I2VD3XJ4m8ueUlsw"
["created"]=>
int(1506032523)
}
I can't understand why there's no the refresh_token key created, I need it in order to get all the time valid tokens to refresh in less than one hour and can use google calls to the user tu publish things or to make things without need to make login again in google.
Thanks
You need to pass in $token (the whole array) ie: refreshToken($token).
Thank you for filing this issue. We asked some clarifying questions or suggested a course of action a week or more ago and never heard back from you. We are unable to proceed with this issue until then, so we are closing it. Please feel free to comment with more information and we will re-open this issue.
Sorry for the delay. I was stopped with the project and now we have reopened again. This solution fails. The refreshToken method is the call to fetchAccessTokenFromRefreshToken() method. As you can see in the Google_Client this definition throws an LogicException when no refresh_token is present:
public function fetchAccessTokenWithRefreshToken($refreshToken = null)
{
if (null === $refreshToken) {
if (!isset($this->token['refresh_token'])) {
throw new LogicException(
'refresh token must be passed in or set as part of setAccessToken'
);
}
...
This means that if I'm not able to get a refresh_token from whenever be, I will not be able to refresh my access token again. Is this a php limitation?
Thanks,
Dani
Hi @mvcmaker, sorry it has taken be so long to circle back around to this one.
Id Tokens are typically involved when you want to use Google Sign-In or more generally Google's OAuth 2.0 just for authentication but have your own resources you want to manage authorization to.
So verifyIdToken is something you will only want to do as often as say 'Sign-up' or 'Lost Password' just to make sure they are who they say they are and get some basic info about them.
Am I guessing your use case right or are there other Google APIs you are integrating into your app?
Hi @mattwhisenhunt My idea is like I do on facebook api is to keep the same token refreshed via refresh token process, each day or each hour in order that I can interact with the google api from one user all the times I want, by exaplme publishing things in the post's google + user, retrieving the profile photo change, etc... But without refreshing the token I can only use one time, the first time that the android app sends me the id token and get retrieve the user information, then after 1 hour, the id token has no sense to exist in our database.
It sounds like where you want to start is https://developers.google.com/identity/protocols/OAuth2WebServer and multi-api.php. Up until now you have been experimenting with a related feature called OpenID Connect which is only the authentication bit of authentication/authorization.
I pointed you to the multi-api example because it sounds like you might want to use more than just Google Plus in the future.
@mattwhisenhunt the only thing I want is the thing that performs the button in the oauth 2.0 playground online tool (https://developers.google.com/oauthplayground), when you go to step 2, you exchange the authorization code for tokens, and you can press whenever you want the refresh access token in order to renew the id_token and give 3600 seconds of new live. This is what I want to do via php.
$client->setAccessType('offline');
@mattwhisenhunt what do you mean with this line of code? Do you mean that must be removed?
Sorry I must have been looking at the other issue you had opened and I had been poring of idtoken.php. You definitely want that line.
access_type
Recommended. Indicates whether your application can refresh access tokens when the user is not present at the browser. Valid parameter values are聽online, which is the default value, andoffline.
Set the value to聽offline聽if your application needs to refresh access tokens when the user is not present at the browser. This is the method of refreshing access tokens described later in this document.
This value instructs the Google authorization server to return a refresh token聽and聽an access token the first time that your application exchanges an authorization code for tokens.聽To set this value in PHP, call the聽setAccessType聽function:$client->setAccessType('offline');
Refreshing an access token (offline access)
Access tokens periodically expire. You can refresh an access token without prompting the user for permission (including when the user is not present) if you requested offline access to the scopes associated with the token.If you use a Google API Client Library, the client object refreshes the access token as needed as long as you configure that object for offline access.
If you are not using a client library, you need to set the access_type HTTP query parameter to offline when redirecting the user to Google's OAuth 2.0 server. In that case, Google's authorization server returns a refresh token when you exchange an authorization code for an access token. Then, if the access token expires (or at any other time), you can use a refresh token to obtain a new access token.
Requesting offline access is a requirement for any application that needs to access a Google API when the user is not present. For example, an app that performs backup services or executes actions at predetermined times needs to be able to refresh its access token when the user is not present. The default style of access is called online.Server-side web applications, installed applications, and devices all obtain refresh tokens during the authorization process.
https://developers.google.com/identity/protocols/OAuth2WebServer#offline
In a nutshell, there's no reason that from my php application I can't update the tokens by using refreshToken due I'm using well the setAccessType to offline. Is this correct?
That is correct.