I use HWIO Bundle for google api and when I have response from google refreshToken = null why? How to refresh token
oAuthToken = {HWI\Bundle\OAuthBundle\Security\Core\Authentication\Token\OAuthToken} [11]
accessToken = "ya29.Ci8lA1JTu9CB81dOFy-nzszViRgCI2CvvKVrCd0Lq-8I0QR_dIrl-_7RccdGt1Islg"
rawToken = {array} [4]
access_token = "ya29.Ci8lA1JTu9CB81dOFy-nzszViRgCI2CvvKVrCd0Lq-8I0QR_dIrl-_7RccdGt1Islg"
token_type = "Bearer"
expires_in = 3578
id_token = "xxxxx"
refreshToken = null
expiresIn = 3578
createdAt = 1468957368
tokenSecret = null
resourceOwnerName = null
because in "name": "google/apiclient", "version": "1.1.7" in function need refresh_token
public function getRefreshToken()
{
if (array_key_exists('refresh_token', $this->token)) {
return $this->token['refresh_token'];
} else {
return null;
}
}
how to refresh token and how to with token get refresh token, for refresh token ?
I try
Go to your account security settings: https://www.google.com/settings/u/1/security.
Click the edit button next to "Authorizing applications and sites".
and not find how to enable refresh token
Try
$client->setAccessType ("offline");
$client->setApprovalPrompt ("force");
this my access token
{"access_token":"ya29.Ci8lA1JTu9CB81dOFy-nzszViRgCI2CvvKVrCd0Lq-8I0QR_dIrl-_7RccdGt1Islg","token_type":"Bearer","expires_in":3578,"id_token":"xxxx","created":1468957368}
not have refresh token because grom google get refreshToken = null ot need set null with key refresh token or this dosn't metter ?
`$client = $this->get('artel.google.api.client');
/** @var CodeUserReference[] $accessToken */
$accessToken = $this->get('doctrine.orm.entity_manager')->getRepository('ArtelProfileBundle:CodeUserReference')
->getReferenceAccessClient($user);
if ($accessToken) {
$client->setAccessToken($accessToken[0]->getAccessTokenClient());
} else {
$view = $this->view(['No accessToken was found for this user id'], 400);
return $this->handleView($view);
}
$isExpired = $client->isAccessTokenExpired(); // true (bool Returns True if the access_token is expired.)
$refresh = $client->getRefreshToken(); //null because not gahe refresh token
$client->getGoogleClient()->setAccessType ("offline"); //your recomendation
$client->getGoogleClient()->setApprovalPrompt ("force"); //your recomendation
$isAgainExpired = $client->isAccessTokenExpired(); // still true (expired)
$service = new \Google_Service_Drive($client->getGoogleClient());
$file = new \Google_Service_Drive_DriveFile();
$file->setName($request->request->get('title')
? $request->request->get('title')
: $request->files->get('file')->getClientOriginalName()
);
$file->setDescription($request->request->get('description'));
$file->setMimeType($request->request->get('mimeType')
? $request->request->get('mimeType')
: $request->files->get('file')->getClientMimeType()
);
// Set the parent folder.
if ($request->request->get('parentId') != null) {
$parent = new Google_Service_Drive_ParentReferen();
$parent->setId($request->request->get('parentId'));
$file->setParents(array($parent));
}
try {
$data = $request->files->get('file');
$createdFile = $service->files->create($file, array(
'data' => $data,
'mimeType' => $request->request->get('mimeType')
? $request->request->get('mimeType')
: $request->files->get('file')->getClientMimeType(),
'uploadType' => 'media'
));
// Uncomment the following line to print the File ID
// print 'File ID: %s' % $createdFile->getId();
return View::create()
->setStatusCode(200)
->setData([$createdFile]);
} catch (\Exception $e) {
$view = $this->view((array) $e->getMessage(), 400);
return $this->handleView($view);
}`
still have exception - The OAuth 2.0 access token has expired, and a refresh token is not available. Refresh tokens are not returned for responses that were auto-approved.
In my code I assumed $client = new Google_Client();. Also, I am not familiar with the way you request the access token.
For you to get the refresh token, you need to specify access_type and approval_prompt in the same place where you specify scope and redirect_uri.
$client = new Google_Client() but in wrapper, in constructor.hwi_oauth:
connect:
account_connector: app.provider.user_provider
firewall_name: secured_area
resource_owners:
google:
type: google
client_id: xxx
client_secret: xxx
scope: "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/drive"
and after I get access token I set it in DB. Then in Action I create wrapper for google api (new Google Client ()) and set this client my accesss token from DB. How to refresh my access token? I try in action use function google api lib setAccessType and setApprovalPrompt, but not efect
$client->getGoogleClient()->setAccessType ("offline"); //your recomendation
$client->getGoogleClient()->setApprovalPrompt ("force"); //your recomendation
when I create object wrapper I create new Google Client
public function __construct(array $config, LoggerInterface $symfonyLogger = null)
{
// True if objects should be returned by the service classes.
// False if associative arrays should be returned (default behavior).
$config['use_objects'] = true;
$client = new \Google_Client($config);
if ($symfonyLogger) {
//BC for Google API 1.0
if (class_exists('\Google_Logger_Psr')) {
$googleLogger = new \Google_Logger_Psr($client, $symfonyLogger);
$client->setLogger($googleLogger);
} else {
$client->setLogger($symfonyLogger);
}
}
$client -> setApplicationName($config['application_name']);
$client -> setClientId($config['oauth2_client_id']);
$client -> setClientSecret($config['oauth2_client_secret']);
$client -> setRedirectUri($config['oauth2_redirect_uri']);
$client -> setDeveloperKey($config['developer_key']);
$this -> client = $client;
}
config this is:
`happy_r_google_api:
application_name: carbon-quanta-137312
oauth2_client_id: xxx.apps.googleusercontent.com
oauth2_client_secret: xxx
oauth2_redirect_uri: null
developer_key: null
site_name: aog.local.com
`
and if in action I set to Google Client some parameters this is same if I add constructorI, so what I'am doing wrong ?
OK.
So from what I understand, you should add to your config :
access_type: offline
approval_prompt: force
And in your else statement
$client->setAccessType ($config['access_type']);
$client->setApprovalPrompt ($config['approval_prompt']);
Yes, I add to wrapper
$client -> setAccessType ($config['access_type']);
$client -> setApprovalPrompt ($config['approval_prompt']);
but still have
"The OAuth 2.0 access token has expired, and a refresh token is not available. Refresh tokens are not returned for responses that were auto-approved."
and after rebuild project, I lost function create and now have insert, this is a magic, I dont change version in composer json :)
$createdFile = $service->files->insert($file, array(
'data' => $data,
'mimeType' => $request->request->get('mimeType')
? $request->request->get('mimeType')
: $request->files->get('file')->getClientMimeType(),
'uploadType' => 'media'
));
early I have
$createdFile = $service->files->create($file, array(
'data' => $data,
'mimeType' => $request->request->get('mimeType')
? $request->request->get('mimeType')
: $request->files->get('file')->getClientMimeType(),
'uploadType' => 'media'
));
I assume you go through the whole process and open a window for the user to give permission to use the account?
Because, if not, then this is probably your problem:
Refresh tokens are not returned for responses that were auto-approved.
And you need to go through that process, as far as I understand.
when user connect to github first they have window with scope, where user accept this scope and after I have in response accessToken.
The "auto-approval" happens when a user has already accepted the authorization prompt, and so is not prompted again. A refresh token is not returned in this case. You can read more about this here.
I assume when you generate the auth URL (using $client->createAuthUrl), you are not setting approval_prompt=force. You can check this by inspecting the URL's query parameters directly. Setting $client->setApprovalPrompt() in the code above will have no effect, this only has effect if added before the authorization URL is created.
I understan. I get access token from HWIO bundle and I add in config HWIO bundle access_type: offline, approval_prompt: force and in response I have refresh token not null
google:
type: google
client_id: xxx
client_secret: xxx
scope: "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/drive"
options:
access_type: offline
approval_prompt: force
@shubaivan it sounds like you figured it out, but if you continue to have issues, I suggest filing an issue with HWIOBundle.
@bshaffer No, I don't have continue problem, now I have refresh_token in response and this issue closed
require_once 'vendor/autoload.php';
session_start();
/*
$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
$client->setScopes('https://www.googleapis.com/auth/youtube');
$client->setRedirectUri($REDIRECT);
$client->setApplicationName($APPNAME);
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
// Define an object that will be used to make all API requests.
$youtube = new Google_Service_YouTube($client);
if (isset($_GET['code'])) {
if (strval($_SESSION['state']) !== strval($_GET['state'])) {
die('The session state did not match.');
}
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
}
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
echo "Access Token: " . json_encode($_SESSION['token']);
}
// Check to ensure that the access token was successfully acquired.
if ($client->getAccessToken()) {
try {
// Call the channels.list method to retrieve information about the
// currently authenticated user's channel.
$channelsResponse = $youtube->channels->listChannels('contentDetails', array('mine' => 'true'));
$htmlBody = '';
foreach ($channelsResponse['items'] as $channel) {
// Extract the unique playlist ID that identifies the list of videos
// uploaded to the channel, and then call the playlistItems.list method
// to retrieve that list.
$uploadsListId = $channel['contentDetails']['relatedPlaylists']['uploads'];
$playlistItemsResponse = $youtube->playlistItems->listPlaylistItems('snippet', array(
'playlistId' => $uploadsListId,
'maxResults' => 50
));
$htmlBody .= "<h3>Videos in list $uploadsListId</h3><ul>";
foreach ($playlistItemsResponse['items'] as $playlistItem) {
$htmlBody .= sprintf('<li>%s (%s)</li>', $playlistItem['snippet']['title'],
$playlistItem['snippet']['resourceId']['videoId']);
}
$htmlBody .= '</ul>';
}
} catch (Google_ServiceException $e) {
$htmlBody .= sprintf('<p>A service error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
} catch (Google_Exception $e) {
$htmlBody .= sprintf('<p>An client error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
}
$_SESSION['token'] = $client->getAccessToken();
} else {
$state = mt_rand();
$client->setState($state);
$_SESSION['state'] = $state;
$authUrl = $client->createAuthUrl();
$htmlBody = <<<END
You need to authorise access before proceeding.
END;
}
?>
// please help me solve this i am not get token
how to get token, for Authorization: Bearer
One should know, not to share there accessToken or any other token in the details.
Hi, any update about this? I'm facing the same issue.
Or is there a way to Make a New Token without user interactions? I mean User must click the url and get the new code and exchange it with the new token?
Most helpful comment
Try