350 votes

Ne pas recevoir le jeton de rafraîchissement de Google OAuth

Je veux obtenir le jeton d'accès de Google. L'API de Google indique que pour obtenir le jeton d'accès, il faut envoyer le code et les autres paramètres à la page de génération du jeton, et la réponse sera un objet JSON comme :

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

Cependant, je ne reçois pas le jeton de rafraîchissement. La réponse dans mon cas est :

{
 "access_token" : "ya29.sddsdsdsdsds_h9v_nF0IR7XcwDK8XFB2EbvtxmgvB-4oZ8oU",
"token_type" : "Bearer",
"expires_in" : 3600
}

1 votes

J'ai eu un problème similaire. Consultez ma réponse aquí

877voto

Rich Sutton Points 1447

El refresh_token n'est fournie que lors de la première autorisation de l'utilisateur. Les autorisations ultérieures, comme celles que vous effectuez lorsque vous testez une intégration OAuth2, ne renverront pas l'indicateur refresh_token encore. :)

  1. Accédez à la page indiquant les applications ayant accès à votre compte : https://myaccount.google.com/u/0/permissions .
  2. Dans le menu des applications tierces, choisissez votre application.
  3. Cliquez sur Supprimer l'accès et ensuite sur Ok pour confirmer
  4. La prochaine demande OAuth2 que vous ferez renverra un fichier refresh_token (à condition qu'il comprenne également le paramètre de requête "access_type=offline").

Alternativement, vous pouvez ajouter les paramètres de requête prompt=consent&access_type=offline à la redirection OAuth (voir le document de Google intitulé OAuth 2.0 pour les applications de serveur Web page).

Cela invitera l'utilisateur à autoriser à nouveau l'application et renverra toujours un refresh_token .

24 votes

Cela n'a pas fonctionné pour moi, mais l'ajout du paramètre "access_type=offline" a semblé faire l'affaire : developers.google.com/accounts/docs/OAuth2WebServer#offline

96 votes

Vous devez access_type=offline dans tous les cas où vous voulez que le refresh_token .

8 votes

Mais comment rafraîchir le jeton après son expiration dans ce cas ?

67voto

Gal Morad Points 161

Afin d'obtenir le jeton de rafraîchissement, vous devez ajouter les deux éléments suivants approval_prompt=force y access_type="offline" Si vous utilisez le client java fourni par Google, cela ressemblera à ceci :

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

AuthorizationCodeRequestUrl authorizationUrl =
            flow.newAuthorizationUrl().setRedirectUri(callBackUrl)
                    .setApprovalPrompt("force")
                    .setAccessType("offline");

1 votes

Dans le nœud : var authUrl = oauth2Client.generateAuthUrl({ access_type : 'offline', scope : SCOPES, approval_prompt : 'force' }) ;

4 votes

C'est scandaleux que google n'ait pas abordé ce point dans sa documentation ou du moins pas dans la documentation php ou oath2 que j'ai regardé pendant 7 heures. Pourquoi diable ce n'est pas en gros caractères dans leur documentation ?

0 votes

Merci ! Docs ici ( github.com/googlesamples/apps-script-oauth2 ) sont très trompeurs sur ce paramètre. Lorsque j'ai ajouté approval_prompt=force, j'ai finalement obtenu un jeton de rafraîchissement.

37voto

billynoah Points 456

J'aimerais ajouter un peu plus d'informations sur ce sujet pour les âmes frustrées qui rencontrent ce problème. La clé pour obtenir un jeton de rafraîchissement pour une application hors ligne est de s'assurer que vous présentez l'icône écran de consentement . El refresh_token n'est retourné qu'immédiatement après que l'utilisateur ait accordé l'autorisation en cliquant sur "Autoriser".

enter image description here

Le problème est apparu pour moi (et je soupçonne beaucoup d'autres personnes) après avoir effectué quelques tests dans un environnement de développement et donc a déjà autorisé ma demande sur un compte donné. Je suis ensuite passé en production et j'ai tenté de m'authentifier à nouveau en utilisant un compte qui était déjà autorisé. Dans ce cas, l'écran de consentement ne s'affiche pas à nouveau et l'api ne retournera pas un nouveau jeton de rafraîchissement . Pour que cela fonctionne, vous devez forcer la réapparition de l'écran de consentement, soit :

prompt=consent

o

approval_prompt=force

L'un ou l'autre fonctionnera mais vous ne devez pas utiliser les deux. A partir de 2021, je recommande d'utiliser prompt=consent puisqu'il remplace l'ancien paramètre approval_prompt et dans certaines versions de l'api, cette dernière était en fait cassée ( https://github.com/googleapis/oauth2client/issues/453 ). Aussi, prompt est une liste délimitée par des espaces, vous pouvez donc la définir comme suit prompt=select_account%20consent si vous voulez les deux.

Bien sûr, vous avez aussi besoin :

access_type=offline

Lecture supplémentaire :

32voto

Norbert Points 301

J'ai cherché une longue nuit et ceci fait l'affaire :

Modifié user-example.php de admin-sdk

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

puis vous obtenez le code à l'url de redirection et l'authentification avec le code et l'obtention du jeton de rafraîchissement.

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

Vous devriez le stocker maintenant ;)

Lorsque votre clé d'accès ne fonctionne plus, faites simplement

$client->refreshToken($theRefreshTokenYouHadStored);

0 votes

Parfait @Norbert, C'est exactement ce dont j'avais besoin.

0 votes

Merci ! Réponse exacte à ma question @Norbert

21voto

jeteon Points 41

Cela m'a causé une certaine confusion et j'ai pensé que je devais partager ce que j'ai appris à la dure :

Lorsque vous demandez l'accès en utilisant le access_type=offline y approval_prompt=force vous devriez recevoir à la fois un accès et un rafraîchir jeton. Le site accès Le jeton expire peu de temps après sa réception et vous devrez le rafraîchir.

Vous avez correctement fait la demande pour obtenir un nouveau accès et a reçu la réponse qui contient votre nouvelle accès jeton. J'ai également été troublé par le fait que je n'ai pas obtenu un nouveau rafraîchir jeton. Cependant, c'est ainsi que cela doit être, puisque vous pouvez utiliser le même rafraîchir jeté encore et encore.

Je pense que certaines des autres réponses supposent que tu voulais t'acheter un nouveau rafraîchir pour une raison quelconque et a suggéré que vous autorisiez à nouveau l'utilisateur, mais en fait, vous n'avez pas besoin de le faire puisque l'identifiant de l'utilisateur a été modifié. rafraîchir que vous avez fonctionnera jusqu'à ce qu'il soit révoqué par l'utilisateur.

1 votes

J'ai un CMS où différents utilisateurs utilisent différents comptes Google pour se connecter à l'api analytique. Cependant, il arrive que plusieurs utilisateurs se connectent en utilisant le même compte google de l'entreprise, mais que chacun veuille accéder à un compte analytics différent. Seul le premier reçoit le jeton de rafraîchissement, alors que tous les autres ne le reçoivent pas et doivent donc se reconnecter toutes les heures. N'y a-t-il pas un moyen d'obtenir le MEME jeton de rafraîchissement pour les authentifications ultérieures au lieu du seul jeton d'accès qui expire dans l'heure ?

1 votes

L'API semble produire le rafraîchir exactement une fois. Tout "partage" du jeton devra se faire dans votre code. Vous devrez cependant veiller à ne pas accorder accidentellement de nouveaux privilèges d'accès aux utilisateurs. Un moyen simple d'y parvenir est de faire en sorte que l'application garde la trace des éléments suivants rafraîchir les jetons et les comptes associés dans leur propre stockage (une "table" distincte en SQLese). Ensuite, lorsque vous souhaitez obtenir un nouveau accès que vous vérifiez et utilisez ce jeton éventuellement commun à partir de là. Mis en œuvre d'une certaine manière, votre code n'a pas besoin de savoir qui a réellement obtenu le jeton.

1 votes

Je ne sais pas comment je pourrais identifier quel jeton de rafraîchissement je dois associer à un nouveau jeton d'accès que je viens de recevoir. Différents utilisateurs effectuent la connexion, et la seule chose qu'ils ont en commun est qu'ils utilisent le même compte Google (e-mail) pour se connecter à l'API. Mais Google ne renvoie pas l'identifiant du compte ou de l'e-mail, il renvoie simplement un jeton. Je ne sais donc pas comment associer les 2 utilisateurs de CMS différents...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X