web-dev-qa-db-fra.com

Comment obtenir un jeton d'accès à l'aide de l'API gmail

J'ai reçu le code d'autorisation après ce document . Mais quand j'ai essayé d'obtenir un jeton d'accès, j'ai toujours eu des erreurs. Quelqu'un peut-il m'aider ?

public String AccessToken()
{
    String accessToken = "";
    StringBuilder strBuild = new StringBuilder();

    String authURL = "https://accounts.google.com/o/oauth2/token?";
    String code = "4/SVisuz_x*********************";
    String client_id = "******************e.apps.googleusercontent.com";
    String client_secret = "*******************";
    String redirect_uri = "urn:ietf:wg:oauth:2.0:oob";
    String grant_type="authorization_code";
    strBuild.append("code=").append(code)
            .append("&client_id=").append(client_id)
            .append("&client_secret=").append(client_secret)
            .append("&redirect_uri=").append(redirect_uri)
            .append("&grant_type=").append(grant_type);
    System.out.println(strBuild.toString());
    try{
        URL obj = new URL(authURL);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
        con.setDoOutput(true);
        con.setRequestMethod("POST");

        con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        con.setRequestProperty("Host", "www.googleapis.com");

        //BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(con.getOutputStream()));
        //bw.write(strBuild.toString());
        //bw.close();

        DataOutputStream wr = new DataOutputStream(con.getOutputStream());
        wr.writeBytes(strBuild.toString());
        wr.flush();
        wr.close();

        //OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream());
        System.out.println(con.getResponseCode());
        System.out.println(con.getResponseMessage());             

    } catch (Exception e)
    {
        System.out.println("Error.");
    }
    return "";
}

quand j'ai couru ce code, la sortie est: 400 Bad Request

11
tqjustc

Comment obtenir un jeton d'accès en utilisant l'API Gmail?

Ans: Selon votre tutoriel suivant , vous utilisez OAuth 2.0. Il existe donc un modèle de base pour accéder à une API Google à l'aide de OAuth 2.0. Il suit 4 étapes:

  1. Obtenez des informations d'identification OAuth 2.0 à partir de la console des développeurs Google.
  2. Obtenez un jeton d'accès à partir du serveur d'autorisations Google.
  3. Envoyez le jeton d'accès à une API.
  4. Actualisez le jeton d'accès, si nécessaire.

Pour plus de détails, vous pouvez suivre le tutoriel - Utilisation de OAuth 2.0 pour accéder aux API Google

Vous devez visiter la console des développeurs Google pour obtenir des informations d'identification OAuth 2.0, telles que client ID et client secret, connues de Google et de votre application.


Analyse de la cause originelle:

Numéro 1:

Après avoir étudié votre code, on en trouve quelques-uns. Si votre code s'exécute correctement, il donne toujours une chaîne vide. Parce que votre méthode AccessToken() renvoie toujours return "";

Numéro 2:

 catch (Exception e)
    {
        System.out.println("Error.");
    }

Votre bloc catch try est bloqué par un bloc d'exceptions. Car il semble que vous n’ayez pas complété votre code correctement. Vous avez manqué encoding et vous avez utilisé JSONObject qui prépare le jeton d'accès. Donc, il donne la sortie comme 

Erreur.

Solution:

J'ai compris que votre code est similaire avec ce tutorial

Comme votre code a besoin de plus de changements pour résoudre votre problème. Je vous propose donc d'utiliser LinkedHashMap ou ArrayList. Ceux-ci fourniront un moyen plus facile de faire la solution. Je vous donne donc 2 exemples de code pour vous faciliter la vie. Vous pouvez choisir n'importe lequel d'entre eux. Vous devez changer refresh_token, client id, client secret and grant type en tant que vôtre.

private String getAccessToken()
{
    try
    {
        Map<String,Object> params = new LinkedHashMap<>();
        params.put("grant_type","refresh_token");
        params.put("client_id",[YOUR CLIENT ID]);
        params.put("client_secret",[YOUR CLIENT SECRET]);
        params.put("refresh_token",[YOUR REFRESH TOKEN]);

        StringBuilder postData = new StringBuilder();
        for(Map.Entry<String,Object> param : params.entrySet())
        {
            if(postData.length() != 0)
            {
                postData.append('&');
            }
            postData.append(URLEncoder.encode(param.getKey(),"UTF-8"));
            postData.append('=');
            postData.append(URLEncoder.encode(String.valueOf(param.getValue()),"UTF-8"));
        }
        byte[] postDataBytes = postData.toString().getBytes("UTF-8");

        URL url = new URL("https://accounts.google.com/o/oauth2/token");
        HttpURLConnection con = (HttpURLConnection)url.openConnection();
        con.setDoOutput(true);
        con.setUseCaches(false);
        con.setRequestMethod("POST");
        con.getOutputStream().write(postDataBytes);

        BufferedReader  reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
        StringBuffer buffer = new StringBuffer();
        for (String line = reader.readLine(); line != null; line = reader.readLine())
        {
            buffer.append(line);
        }

        JSONObject json = new JSONObject(buffer.toString());
        String accessToken = json.getString("access_token");
        return accessToken;
    }
    catch (Exception ex)
    {
        ex.printStackTrace(); 
    }
    return null;
}

Pour accéder à Google Play pour les développeurs Android api, vous devez passer le jeton d'actualisation précédent pour obtenir le jeton d'accès

private String getAccessToken(String refreshToken){

HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("https://accounts.google.com/o/oauth2/token");
try 
{
    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(4);
    nameValuePairs.add(new BasicNameValuePair("grant_type",    "refresh_token"));
    nameValuePairs.add(new BasicNameValuePair("client_id",     GOOGLE_CLIENT_ID));
    nameValuePairs.add(new BasicNameValuePair("client_secret", GOOGLE_CLIENT_SECRET));
    nameValuePairs.add(new BasicNameValuePair("refresh_token", refreshToken));
    post.setEntity(new UrlEncodedFormEntity(nameValuePairs));

    org.Apache.http.HttpResponse response = client.execute(post);
    BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
    StringBuffer buffer = new StringBuffer();
    for (String line = reader.readLine(); line != null; line = reader.readLine())
    {
        buffer.append(line);
    }

    JSONObject json = new JSONObject(buffer.toString());
    String accessToken = json.getString("access_token");

    return accessToken;

}
catch (IOException e) { e.printStackTrace(); }

return null;
}

Lien de ressource:

J'espère que cette samples et resource link vous aideront à résoudre votre problème et à accéder à access token.


Qu'est-ce que 400 mauvaise requête?

Ans: Cela indique que la requête n'était pas valide. L'ID parent était manquant ou la combinaison de dimensions ou de métriques demandée n'était pas valide.

Action recommandée: Vous devez modifier la requête d'API pour que celle-ci fonctionne.

Pour HTTP/1.1 400 Bad Request error, vous pouvez passer par mon autre réponse . Cela vous aidera à comprendre le which Host you need to use et les conditions que vous devez appliquer.

Pourquoi le jeton expire? Quelle est la limite de jeton?

Un jeton peut cesser de fonctionner pour l'une des raisons suivantes:

  1. L'utilisateur a revoked accès.
  2. Le jeton n'a pas été utilisé pour six months.
  3. Le user changed passwords et le jeton contiennent les étendues Gmail, Agenda, Contacts ou Hangouts.
  4. Le compte d'utilisateur a exceeded a certain number of token requests.

Il y a currently a limit of 25 refresh tokens per user account per client. Si la limite est atteinte, la création d'un nouveau jeton invalide automatiquement le jeton le plus ancien sans avertissement. Cette limite ne s'applique pas aux comptes de service.

Quelles précautions faut-il suivre?

Précautions - 1:

Certaines demandes nécessitent une étape d'authentification à laquelle l'utilisateur se connecte avec leur compte Google. Après s'être connecté, il est demandé à l'utilisateur si ils sont disposés à accorder les autorisations correspondant à votre application demande. Ce processus s'appelle le consentement de l'utilisateur.

Si l'utilisateur accorde l'autorisation, le serveur d'autorisations Google envoie à votre application un jeton d'accès (ou un code d'autorisation que votre application peut utiliser pour obtenir un jeton d'accès). Si l'utilisateur le fait n'accorde pas l'autorisation, le serveur renvoie une erreur.

Précautions - 2:

Si un jeton d'accès est émis pour l'API Google+, celui-ci n'accorde pas accès à l'API Google Contacts. Vous pouvez cependant envoyer cet accès jeton à l'API Google+ plusieurs fois pour des opérations similaires.

Précautions - 3:

Un jeton d'accès a généralement une date d'expiration d'une heure après le vous obtiendrez une erreur si vous essayez de l'utiliser. Identifiant Google prend en charge le "rafraîchissement" automatique du jeton, ce qui signifie simplement obtenir un nouveau jeton d'accès.

Enregistrez des jetons d'actualisation dans un stockage à long terme sécurisé et continuez à utiliser eux tant qu'ils restent valables. Les limites s'appliquent au nombre de actualise les jetons émis par combinaison client-utilisateur et par utilisateur sur tous les clients, et ces limites sont différentes. Si ton application demande suffisamment de jetons d'actualisation pour aller sur l'un des limites, les anciens jetons d'actualisation cessent de fonctionner.

9
SkyWalker

Vous n'utilisez pas le bon terminal. Essayez de changer la authURL en https://www.googleapis.com/oauth2/v4/token

De la documentation:

Pour créer cette demande de jeton, envoyez une demande HTTP POST au point de terminaison/oauth2/v4/token.

La demande réelle pourrait ressembler à ceci:

POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded

code=4/v6xr77ewYqhvHSyW6UJ1w7jKwAzu&
client_id=8819981768.apps.googleusercontent.com&
client_secret=your_client_secret&
redirect_uri=https://oauth2-login-demo.appspot.com/code&
grant_type=authorization_code

Référencehttps://developers.google.com/identity/protocols/OAuth2InstalledApp#handlingtheresponse

3
newhouse

Pour moi, votre requête est correcte , je l'ai essayée avec Curl. Je reçois également une requête 'HTTP/1.1 400 Bad Request' avec la raison pour laquelle elle a échoué: 'invalid_grant':

curl -X POST https://www.googleapis.com/oauth2/v4/token -d 'code=4/SVisuz_x*********************&client_id=*******************7vet.apps.googleusercontent.com&client_secret=***************&redirect_uri=https://oauth2-login-demo.appspot.com/code&grant_type=authorization_code'

Je reçois (HTTP/1.1 400 Bad Request):

{
 "error": "invalid_grant",
 "error_description": "Code was already redeemed."
}

Maintenant, en utilisant HttpClient à partir d'Apache:

URL obj = new URL(authURL);
HttpClient client = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(authURL);
post.addHeader("Content-Type", "application/x-www-form-urlencoded");
post.addHeader("Host", "www.googleapis.com");
post.setEntity(new StringEntity(strBuild.toString()));

HttpResponse resp = client.execute(post);
System.out.println(resp.getStatusLine());
System.out.println(EntityUtils.toString(resp.getEntity()));

Je vois dans ma console:

HTTP/1.1 400 Bad Request
{
 "error": "invalid_grant",
 "error_description": "Code was already redeemed."
}

Êtes-vous sûr que le code que vous utilisez est toujours valide? Pouvez-vous essayer avec un nouveau?

Je pense que je comprends ce qui ne va pas:

  1. comme @newhouse a dit, vous devriez POST pour https://www.googleapis.com/oauth2/v4/token et non https://accounts.google.com/o/oauth2/token (@newhouse je vous ai donné un +1 :))

    (https://www.googleapis.com/oauth2/v4/token est pour obtenir le authorization_code et https://accounts.google.com/o/oauth2/token est pour obtenir le code).

  2. Vous ne pouvez pas utiliser la même code plus d'une fois.

    Tout le reste semble en ordre donc, si vous continuez à obtenir 400, vous essayez probablement d'utiliser la variable code que vous avez plus d'une fois (alors vous aurez 400 à chaque fois, encore et encore).

* Vous devriez également perdre la con.setRequestProperty("Host", "www.googleapis.com"); 

0
Yoav Aharoni

Voir: https://developers.google.com/Android-publisher/authorization

Vous avez déjà un code d'autorisation appelé "Actualiser le jeton". Veuillez le garder en lieu sûr. Vous pouvez utiliser "Actualiser le jeton" pour générer le "jeton d'accès".

Pour obtenir un "jeton d'accès", veuillez faire une demande de publication à l'URL suivante.

https://accounts.google.com/o/oauth2/token

Paramètres:

  • grant_type
  • identité du client
  • client_secret
  • refresh_token

où "grant_type" devrait être "refresh_token"

Nous utilisons PHP pour faire de même, voici le code PHP pour votre référence

    $curl = curl_init();

    curl_setopt_array($curl, array(
    CURLOPT_RETURNTRANSFER => 1,
    CURLOPT_URL => 'https://accounts.google.com/o/oauth2/token',
    CURLOPT_USERAGENT => 'Pocket Experts Services',
    CURLOPT_POST => 1,
    CURLOPT_POSTFIELDS => array(
    "grant_type" => "refresh_token",
    "client_id" => $GOOGLE_CLIENT_ID,
    "client_secret" => $GOOGLE_CLIENT_SECRET,
    "refresh_token" => $GOOGLE_REFRESH_TOKEN,
    )));


    // Send the request & save response to $resp
    $resp = curl_exec($curl);

J'espère que cela vous aidera.

0
Umang Joshi