No recibir el token de actualización de Google OAuth

Resuelto Muhammad Usman asked hace 12 años • 20 respuestas

Quiero obtener el token de acceso de Google. La API de Google dice que para obtener el token de acceso, envíe el código y otros parámetros a la página de generación del token y la respuesta será un objeto JSON como:

{
"access_token" : "ya29.AHES6ZTtm7SuokEB-RGtbBty9IIlNiP9-eNMMQKtXdMP3sfjL1Fc",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "1/HKSmLFXzqP0leUihZp2xUt3-5wkU7Gmu2Os_eBnzw74"
}

Sin embargo, no recibo el token de actualización. La respuesta en mi caso es:

{
 "access_token" : "ya29.sddsdsdsdsds_h9v_nF0IR7XcwDK8XFB2EbvtxmgvB-4oZ8oU",
"token_type" : "Bearer",
"expires_in" : 3600
}
Muhammad Usman avatar May 31 '12 12:05 Muhammad Usman
Aceptado

Sólo se refresh_tokenproporciona con la primera autorización del usuario. Las autorizaciones posteriores, como las que realiza mientras prueba una integración OAuth2, no devolverán el refresh_tokenpermiso. :)

  1. Vaya a la página que muestra las aplicaciones con acceso a su cuenta: https://myaccount.google.com/u/0/permissions .
  2. En el menú Aplicaciones de terceros, elija su aplicación.
  3. Haga clic en Eliminar acceso y luego haga clic en Aceptar para confirmar.
  4. La próxima solicitud de OAuth2 que realice devolverá un refresh_token(siempre que también incluya el parámetro de consulta 'access_type=offline'.

Alternativamente, puede agregar los parámetros de consulta a la redirección de OAuth (consulte la página OAuth 2.0 para aplicaciones de servidor webprompt=consent&access_type=offline de Google ).

Esto solicitará al usuario que autorice la aplicación nuevamente y siempre devolverá un archivo refresh_token.

Rich Sutton avatar Jun 01 '2012 21:06 Rich Sutton

Para obtener el token de actualización, debe agregar ambos approval_prompt=forcey, access_type="offline" si está utilizando el cliente Java proporcionado por Google, se verá así:

GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
            HTTP_TRANSPORT, JSON_FACTORY, getClientSecrets(), scopes)
            .build();

AuthorizationCodeRequestUrl authorizationUrl =
            flow.newAuthorizationUrl().setRedirectUri(callBackUrl)
                    .setApprovalPrompt("force")
                    .setAccessType("offline");
Gal Morad avatar Jan 01 '2013 08:01 Gal Morad

Me gustaría agregar un poco más de información sobre este tema para aquellas almas frustradas que enfrentan este problema. La clave para obtener un token de actualización para una aplicación fuera de línea es asegurarse de presentar la pantalla de consentimiento . Solo se refresh_tokendevuelve inmediatamente después de que un usuario otorga autorización haciendo clic en "Permitir".

ingrese la descripción de la imagen aquí

El problema surgió para mí (y sospecho que para muchos otros) después de haber estado realizando algunas pruebas en un entorno de desarrollo y, por lo tanto, ya había autorizado mi aplicación en una cuenta determinada. Luego pasé a producción e intenté autenticarme nuevamente usando una cuenta que ya estaba autorizada. En este caso, la pantalla de consentimiento no volverá a aparecer y la API no devolverá un nuevo token de actualización . Para que esto funcione, debe forzar que la pantalla de consentimiento vuelva a aparecer:

prompt=consent

o

approval_prompt=force

Cualquiera de los dos funcionará, pero no debes usar ambos. A partir de 2021, recomendaría su usoprompt=consent , ya que reemplaza el parámetro anterior approval_prompty, en algunas versiones de la API, este último estaba roto ( https://github.com/googleapis/oauth2client/issues/453 ). Además, prompthay una lista delimitada por espacios para que puedas configurarla prompt=select_account%20consentsi quieres ambas cosas.

Por supuesto también necesitas:

access_type=offline

Lectura adicional:

  • Documentos: https://developers.google.com/identity/protocols/oauth2/web-server#request-parameter-prompt
  • Documentos: https://developers.google.com/identity/protocols/oauth2/openid-connect#re-consent
  • Discusión sobre este problema: https://github.com/googleapis/google-api-python-client/issues/213

Busqué durante una larga noche y esto está funcionando:

User-example.php modificado desde admin-sdk

$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$authUrl = $client->createAuthUrl();
echo "<a class='login' href='" . $authUrl . "'>Connect Me!</a>";

luego obtienes el código en la URL de redireccionamiento y te autentificas con el código y obtienes el token de actualización.

$client()->authenticate($_GET['code']);
echo $client()->getRefreshToken();

Deberías guardarlo ahora ;)

Cuando su clave de acceso se agote, simplemente hágalo

$client->refreshToken($theRefreshTokenYouHadStored);
Norbert avatar Nov 06 '2014 12:11 Norbert

Esto me ha causado cierta confusión, así que pensé en compartir lo que he aprendido de la manera más difícil:

Cuando solicita acceso utilizando los parámetros access_type=offliney approval_prompt=force, debería recibir un token de acceso y un token de actualización . El token de acceso caduca poco después de recibirlo y deberá actualizarlo.

Realizó correctamente la solicitud para obtener un nuevo token de acceso y recibió la respuesta que tiene su nuevo token de acceso . También me confundió el hecho de que no recibí un nuevo token de actualización . Sin embargo, así es como debe ser, ya que puedes usar el mismo token de actualización una y otra vez.

Creo que algunas de las otras respuestas suponen que deseaba obtener un nuevo token de actualización por algún motivo y sugirieron que volviera a autorizar al usuario, pero en realidad no es necesario, ya que el token de actualización que tiene funcionará hasta revocada por el usuario.

jeteon avatar May 15 '2015 13:05 jeteon