Google api refresh_token null и как обновить токен доступа
Я использую HWIO Bundle для google api, и когда у меня есть ответ от google refreshToken = null, почему? Как обновить токен
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
потому что в google/apiclient, "version": "1.1.7" в функции требуется refresh_token
public function getRefreshToken()
{
if (array_key_exists('refresh_token', $this->token)) {
return $this->token['refresh_token'];
} else {
return null;
}
}
этот мой токен доступа
{"access_token":"ya29.Ci8lA1JTu9CB81dOFy-nzszViRgCI2CvvKVrCd0Lq-8I0QR_dIrl-_7RccdGt1Islg","token_type":"Bearer","expires_in":3578,"id_token":"xxxx","created":1468957368}
не обновить токен, потому что из google get refreshToken = null или нужно установить значение null с токеном обновления ключа или этим не согласен?
$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"); //some recomendation
$client->getGoogleClient()->setApprovalPrompt ("force"); //some recomendation
$isAgainExpired = $client->isAccessTokenExpired(); // still true (expired)
все еще есть исключение - 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.
как обновить токен и как с помощью токена получить токен обновления, для обновления токена?
Я пытаюсь
- В моем коде тоже
$client = new Google_Client()
, но в оболочке, в конструкторе.
-
Я получаю токен доступа из пакета HWIO:
hwi_oauth:
connect:
account_connector: app.provider.user_provider
firewall_name: secured_area
resource_owners:
google:
type: google
client_id: xxx.apps.googleusercontent.com
client_secret: xxx
scope: "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/drive"
и после того, как я получу токен доступа, я установил его в БД. Затем в Action я создаю оболочку для google api (новый Google Client()) и устанавливаю для этого клиента мой токен доступа из БД. Как обновить токен доступа? Я пытаюсь в действии использовать функцию google api lib setAccessType и setApprovalPrompt, но не efect
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']);
$client -> setAccessType ($config['access_type']);
$client -> setApprovalPrompt ($config['approval_prompt']);
$this -> client = $client;
}
config это:
happy_r_google_api:
application_name: carbon-quanta-137312
oauth2_client_id: xxxx.apps.googleusercontent.com
oauth2_client_secret: xxx
oauth2_redirect_uri: null
developer_key: null
site_name: aog.local.com
access_type: offline
approval_prompt: force
и если в действии я установил в Google Client некоторые параметры, это будет одинаково, если я добавлю конструктор, так что я делаю неправильно?
Ответы
Ответ 1
refresh_token возвращается только при первом запросе. Когда вы обновляете токен доступа во второй раз, он возвращает все, кроме refresh_token, а file_put_contents удаляет refresh_token, когда это происходит во второй раз.
Модификация кода следующим образом будет сливаться в исходном токене доступа с новым (см.: array_merge). Таким образом, вы сможете сохранить refresh_token для будущих запросов. Я опубликовал следующее исправление для Google, надеюсь, что они обновят его в какой-то момент.
Подробнее см. в документах
// Refresh the token if it expired.
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
$newAccessToken = $client->getAccessToken();
$accessToken = array_merge($accessToken, $newAccessToken);
file_put_contents($credentialsPath, json_encode($accessToken));
}
Ответ 2
В протокол OAuth 2.0 ваше приложение запрашивает авторизацию для доступа к ресурсам, которые идентифицируются областями, и при условии, что пользователь аутентифицирован и одобряет, ваше приложение получает недолгосрочные токены доступа, которые позволяют ему обращаться к этим ресурсам и (необязательно) обновлять токены, чтобы обеспечить долгосрочный доступ.
Идея токенов обновления заключается в том, что если токен доступа скомпрометирован, потому что он недолговечен, у злоумышленника есть ограниченное окно, в котором он будет злоупотреблять им.
Обновить токены, если они скомпрометированы, бесполезны, потому что злоумышленник требует идентификатор клиента и секрет в дополнение к токере обновления, чтобы получить токен доступа.
Причина, по которой токен может перестать работать:
- Пользователь отменил доступ.
- токен не использовался в течение шести месяцев.
- Пользователь изменил пароли, а токен содержит области Gmail, Календарь, Контакты или Hangouts.
- Учетная запись пользователя превысила определенное количество запросов токенов.
В настоящее время существует ограничение на 25 токенов обновления для каждой учетной записи пользователя на одного клиента. Если предел достигнут, создание нового токена автоматически аннулирует старейший токен без предупреждения. Это ограничение не распространяется на учетные записи служб.
Здесь в соответствующем бите SO обсуждаются причины получения маркера NULL: Получение нулевого токена обновления
Ответ 3
Я подставил. Я получаю токен доступа из пакета HWIO и добавляю в конфигурацию HWIO bundle access_type: offline, assert_prompt: force и в ответ я обновляю токен, но не 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
Ответ 4
Половина ответа уже ответила Аритран.
Истекщий токен отправляется только в первый раз, когда вы авторизуете свою учетную запись. После этого вы больше не сможете его получать, и поэтому вам нужно сохранить его с самого начала, а затем при каждом обновлении, слить старый и новый массивы.
Другая половина ответа - как удалить и снова получить этот токен, иначе вам нужно будет каждый раз тестировать новую учетную запись google.
- Перейдите в настройки безопасности своей учетной записи: https://www.google.com/settings/u/1/security.
- Перейдите к разделу "Авторизация приложений и сайтов", затем нажмите "Просмотреть все".
- Затем "Отменить доступ" к вашему приложению.
- Сделайте новый запрос OAuth2. Это вернет refresh_token.
Не забудьте добавить access_type=offline
к вашему запросу