2017-09-05 4 views
0

Jusqu'à au moins la fin du mois de juin de cette année (2017) (mes utilisateurs sont des enseignants donc n'accédez pas beaucoup à nos applications pendant l'été ...) J'ai eu le flux de travail suivant.gapi grantOfflineAccess code_accès à refresh_token

Les utilisateurs se connecteraient via le Web en utilisant la bibliothèque gapi. Pour les nouveaux utilisateurs, signe réussi à appeler alors

gapi.auth2.getAuthInstance().currentUser.get().grantOfflineAccess() 

pour obtenir un code qui a été ensuite envoyé à notre back-end Java aux échanges le code pour un refresh_token. Nous utilisons la bibliothèque google-api-client (v 1.22.0) pour vérifier le id_token de l'utilisateur qui est retourné lors de la connexion initiale, puis un appel REST pour obtenir le refresh_token retourné.

HttpClient client = new DefaultHttpClient(); 
HttpPost post  = new HttpPost("https://www.googleapis.com/oauth2/v4/token"); 
List<NameValuePair> pairs = new ArrayList<NameValuePair>(); 
pairs.add(new BasicNameValuePair("code", r.getRefreshCode())); 
pairs.add(new BasicNameValuePair("redirect_uri", "postmessage")); 
pairs.add(new BasicNameValuePair("client_id", clientInfo.getClientId())); 
pairs.add(new BasicNameValuePair("client_secret", clientInfo.getClientSecret())); 
pairs.add(new BasicNameValuePair("grant_type", "authorization_code")); 
post.setEntity(new UrlEncodedFormEntity(pairs)); 
org.apache.http.HttpResponse response = client.execute(post); 
String responseBody = EntityUtils.toString(response.getEntity()); 

au moins jusqu'à Juin, l'appel REST retourné un objet JSON sous la forme suivante

{ 
    access_token: '', 
    token_type: '', 
    expires_in: 3600, 
    id_token: '', 
    refresh_token: '' 
} 

... Mais maintenant (dans les deux dernières semaines de toute façon), le jeton de rafraîchissement est pas inclus dans la réponse de l'appel REST. Qu'est-ce qui a changé, ou que dois-je faire différemment pour que le refresh_token soit utilisé par nos serveurs?

Dans le OAuth 2.0 Playground fourni par Google, quand on utilise les mêmes champs que mon application et l'échange le « code » pour un jeton de rafraîchissement, je reçois un objet de retour avec

{ 
    "access_token": "", 
    "token_type": "", 
    "expires_in": 3600, 
    "refresh_token": "" 
} 

Alors, évidemment le Playground fait quelque chose différemment que moi. J'ai regardé la demande envoyer dans le débogueur Chrome et il ressemble à ce que je fais.

Répondre

0

Je résolu le problème en modifiant l'appel grantOfflineAccess inclure les éléments suivants ...

gapi.auth2.getAuthInstance().currentUser.get().grantOfflineAccess({ 
    access_type: 'offline', 
    prompt:  'consent', 
    scope:  SCOPES.join(' ') 
}) 

... L'importante addition étant l'invite. Autant que je sache, la fenêtre permettant de fournir un consentement pour l'accès hors connexion était automatiquement fermée, de sorte que le code retourné n'était pas valide pour produire un jeton d'actualisation du côté Java. J'ai également mis à jour le code Java pour utiliser directement la bibliothèque cliente Google au lieu d'un appel REST (bien que la modification JS ait encore entraîné la récupération d'un jeton d'actualisation avec l'appel REST, donc uniquement pour la cohérence).

GoogleAuthorizationCodeTokenRequest request = 
    new GoogleAuthorizationCodeTokenRequest(new NetHttpTransport(), new JacksonFactory(), 
            clientInfo.getClientId(), clientInfo.getClientSecret(), 
            r.getRefreshCode(), "postmessage"); 
request.setGrantType("authorization_code"); 
GoogleTokenResponse response = request.execute();