keep - google-api-php-client
Cuenta de servicio de unidad de Google y "Cliente no autorizado o alcance en solicitud" (1)
Tengo 3 cuentas de servicio que están utilizando el disco SDK.
1, funciona, 2 no.
El error que aparece es "Error al actualizar el token OAuth2, mensaje: ''{" error ":" cliente no autorizado "," error_description ":" Cliente no autorizado o alcance en la solicitud ".}''"
Las 3 cuentas están registradas en la consola de desarrollador. Los 3 están autorizados para el "acceso de API de cliente gestionado" dentro de Google Apps Console. Todos los 3 tienen el alcance " https://www.googleapis.com/auth/drive.readonly ". Todos los 3 en la unidad tienen una carpeta específica para compartir para "solo ver".
Estoy usando PHP y paso un parámetro a la página que se llama "tipo" y refleja para qué sirve la cuenta, 1 para público, 1 para miembro y 1 para administrador.
Por ejemplo
http://www.somehost.com/oauth_client.php?type=googledrive_admin
El certificado p12 y los valores de usuario se almacenan en el servidor. Todos los archivos "ini" tienen la misma estructura de valores, client_id, client_email, scope y query filter. En todos los casos, el único elemento que cambia entre los archivos es client_id y client_email.
Mi código es el siguiente:
<?php
include (__DIR__ . "/google-api-php-client/autoload.php");
google_api_php_client_autoload("Google_Auth_AssertionCredentials");
google_api_php_client_autoload("Google_Client");
google_api_php_client_autoload("Google_Service_Drive");
google_api_php_client_autoload("Google_Service_OAuth2");
$type = $_GET[''type''];
$path = __DIR__ . "/secure/";
$certificate = $path . $type . ".p12";
$ini_path = $path . $type . ".ini";
$ini = parse_ini_file($ini_path);
$service_scope = $ini[''scope''];
$service_account_id = $ini[''id''];
$service_account_email = $ini[''email''];
$service_query = $ini[''q''];
$service_account_key = file_get_contents($certificate);
$credentials = new Google_Auth_AssertionCredentials(
$service_account_email,
array($service_scope),
$service_account_key
);
$credentials -> sub = $service_account_email;
$google_client = new Google_Client();
$google_client -> setAssertionCredentials($credentials);
if ($google_client -> getAuth() -> isAccessTokenExpired()) {
$google_client -> getAuth() -> refreshTokenWithAssertion(); **//FAILS HERE**
}
$drive = new Google_Service_Drive($google_client);
$result = array();
$pageToken = NULL;
do {
try {
$parameters = array();
if ($pageToken) {
$parameters[''pageToken''] = $pageToken;
}
$parameters[''q''] = $service_query;
$files = $drive -> files -> listFiles($parameters);
$result = array_merge($result, $files -> getItems());
$pageToken = $files -> getNextPageToken();
} catch (Exception $e) {
print "An error occurred: " . $e -> getMessage();
$pageToken = NULL;
}
} while ($pageToken);
echo json_encode($result) . "/n";
?>
Cada archivo ini está estructurado de la siguiente manera
id="35{code}.apps.googleusercontent.com"
email="35{code}@developer.gserviceaccount.com"
scope="https://www.googleapis.com/auth/drive.readonly"
q="mimeType != ''application/vnd.google-apps.folder''"
Lo que no puedo entender es por qué esto funciona para una cuenta de servicio y no para las otras cuando he pasado por el mismo proceso para todas ellas. Cualquier idea y ayuda apreciada.
Gracias por esta publicación y por su comentario sobre "Se resolvió quitando la línea $credentials -> sub = $service_account_email;
"
Me enfrento a un problema similar aquí . Aparentemente, $credentials -> sub = $service_account_email
solo se acepta para la primera cuenta de servicio primaria creada en Google Developers Console. Además de eso, también producirá errores inesperados con ciertos ámbitos OAuth2 (como lo que encontré con Fusion Tables).
Por lo tanto, aquí está el consejo general:
NO incluya
$credentials -> sub = $service_account_email
innecesariamente.
Solo haga esto cuando intente suplantar a un usuario diferente (con la condición de que la configuración adecuada se haya realizado correctamente en la Consola de administración de Google Apps).
Aunque no se produzca ningún error en ciertos casos, existen algunos comportamientos inesperados al incluir una dirección de correo electrónico de la cuenta de servicio en el conjunto de notificaciones de JWT como el valor del campo "secundario".