devstory

Utilisation de l'API Java Scribe OAuth avec Google OAuth2

  1. Des problème de Google Oauth1a
  2. Créer le projet dans Google Developers Console
  3. Créer rapidement un projet & déclarer la bibliothèque Scribe Java API
  4. Code Project

1. Des problème de Google Oauth1a

Il y a un problème avec Google OAuth 1a. A partir de 20 avril 2015, google ne soutient plus officiellment le protocole OAuth 1. Si vous utilisez Scribe Java API pour travailler avec Google OAuth 1.0, vous devez changer le code.

Dans ce document, je vais vous donner des instructions de l'utiliser Scribe Java API pour travailler avec Google OAuth 2.0

2. Créer le projet dans Google Developers Console

In the first time, you do not have any Project, so you have to create it. In most cases, you should name Project same your Website name (It is not compulsory).
Project Name: ExampleWebsite
Project has been created:
Goto "APIs and auth/Consent screen", to create a Product Name.
Create Client ID:
In case you use OAuth2.0 on a web application, you will have to create ClientID for that web application. Parallel, you declare the redirecting link (The link will be redirected to after user logs in his/her google account and allows your application to connect with Google OAuth).
ClientID is created, in which the two most important kinds of information are Client ID and Client Secret. You need to have it in Java code (Illustrated in the following example).
Note: You can create multiple ClientIDinformation for your different applications.

3. Créer rapidement un projet & déclarer la bibliothèque Scribe Java API

  • File/New/Others
Votre projet est créé.
La configuration de Maven utilise Scribe Java API:
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                  http://maven.apache.org/xsd/maven-4.0.0.xsd">
                  
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.o7planning</groupId>
    <artifactId>ScribeGoogleOAuth2</artifactId>
    <version>0.0.1-SNAPSHOT</version>


    <dependencies>

        <!-- http://mvnrepository.com/artifact/org.scribe/scribe -->
        <dependency>
            <groupId>org.scribe</groupId>
            <artifactId>scribe</artifactId>
            <version>1.3.7</version>
        </dependency>

    </dependencies>
    
</project>

4. Code Project

Scribe Java API est un APIqui vous aide de travailler plus facilement avec OAuth, il cache les différences entre des prestataires de service OAuth (Google, yahoo, facebook,..), et soutient OAuth 1a, OAuth 2.0
Par exemple, pour travailler avec LinkIn,votre code est:
OAuthService service = new ServiceBuilder()
                                 .provider(LinkedInApi.class)
                                 .apiKey(YOUR_API_KEY)
                                 .apiSecret(YOUR_API_SECRET)
                                 .build();
Par exemple, pour travailler avec Google OAuth 1a votre code est:
OAuthService service = new ServiceBuilder()
                                 .provider(GoogleApi.class)
                                 .apiKey(YOUR_API_KEY)
                                 .apiSecret(YOUR_API_SECRET)
                                 .build();
Scribe Java API est disponible des API pour différents prestataires:
  • FacebookApi
  • GoogleApi
  • FoursquareApi
  • Foursquare2Api
  • YahooApi
  • TwitterApi
  • ....
Malheureusement, GooleApi n'utilise que pour Google OAuth 1, pas pour Google OAuth 2.0, et vous ne pouvez pas trouver la classe Google2Api dans la bibliothèque de Scribe 1.3.7 (Peut être c'est à cause du problème du droit d'auteur).

Donc dans votre projet, vous devez créer 2 classes Google2Api, et notez qu'elles doivent être contenu dans le package org.scribe.builder.api:
Google2Api.java
package org.scribe.builder.api;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.scribe.exceptions.OAuthException;
import org.scribe.extractors.AccessTokenExtractor;
import org.scribe.model.OAuthConfig;
import org.scribe.model.OAuthConstants;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuth20ServiceImpl;
import org.scribe.oauth.OAuthService;
import org.scribe.utils.OAuthEncoder;
import org.scribe.utils.Preconditions;

/**
* Google OAuth2.0 Released under the same license as scribe (MIT License)
*
* @author yincrash
*
*/
public class Google2Api extends DefaultApi20 {

    private static final String AUTHORIZE_URL = "https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=%s&redirect_uri=%s";
    private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL
            + "&scope=%s";

    @Override
    public String getAccessTokenEndpoint() {
        return "https://accounts.google.com/o/oauth2/token";
    }

    @Override
    public AccessTokenExtractor getAccessTokenExtractor() {
        return new AccessTokenExtractor() {

            @Override
            public Token extract(String response) {
                Preconditions
                        .checkEmptyString(response,
                                "Response body is incorrect. Can't extract a token from an empty string");

                Matcher matcher = Pattern.compile(
                        "\"access_token\" : \"([^&\"]+)\"").matcher(response);
                if (matcher.find()) {
                    String token = OAuthEncoder.decode(matcher.group(1));
                    return new Token(token, "", response);
                } else {
                    throw new OAuthException(
                            "Response body is incorrect. Can't extract a token from this: '"
                                    + response + "'", null);
                }
            }
        };
    }

    @Override
    public String getAuthorizationUrl(OAuthConfig config) {
        // Append scope if present
        if (config.hasScope()) {
            return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(),
                    OAuthEncoder.encode(config.getCallback()),
                    OAuthEncoder.encode(config.getScope()));
        } else {
            return String.format(AUTHORIZE_URL, config.getApiKey(),
                    OAuthEncoder.encode(config.getCallback()));
        }
    }

    @Override
    public Verb getAccessTokenVerb() {
        return Verb.POST;
    }

    @Override
    public OAuthService createService(OAuthConfig config) {
        return new GoogleOAuth2Service(this, config);
    }

    private class GoogleOAuth2Service extends OAuth20ServiceImpl {

        private static final String GRANT_TYPE_AUTHORIZATION_CODE = "authorization_code";
        private static final String GRANT_TYPE = "grant_type";
        private DefaultApi20 api;
        private OAuthConfig config;

        public GoogleOAuth2Service(DefaultApi20 api, OAuthConfig config) {
            super(api, config);
            this.api = api;
            this.config = config;
        }

        @Override
        public Token getAccessToken(Token requestToken, Verifier verifier) {
            OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(),
                    api.getAccessTokenEndpoint());
            switch (api.getAccessTokenVerb()) {
            case POST:
                request.addBodyParameter(OAuthConstants.CLIENT_ID,
                        config.getApiKey());
                request.addBodyParameter(OAuthConstants.CLIENT_SECRET,
                        config.getApiSecret());
                request.addBodyParameter(OAuthConstants.CODE,
                        verifier.getValue());
                request.addBodyParameter(OAuthConstants.REDIRECT_URI,
                        config.getCallback());
                request.addBodyParameter(GRANT_TYPE,
                        GRANT_TYPE_AUTHORIZATION_CODE);
                break;
            case GET:
            default:
                request.addQuerystringParameter(OAuthConstants.CLIENT_ID,
                        config.getApiKey());
                request.addQuerystringParameter(OAuthConstants.CLIENT_SECRET,
                        config.getApiSecret());
                request.addQuerystringParameter(OAuthConstants.CODE,
                        verifier.getValue());
                request.addQuerystringParameter(OAuthConstants.REDIRECT_URI,
                        config.getCallback());
                if (config.hasScope())
                    request.addQuerystringParameter(OAuthConstants.SCOPE,
                            config.getScope());
            }
            Response response = request.send();
            return api.getAccessTokenExtractor().extract(response.getBody());
        }
    }

}
Créez une classe MyConstants pour stocker Google Client ID et Client Secret que vous avez créé auparavant sur Google Developers Console.
MyConstants.java
package org.o7planning.tutorial.scribegoogle;

public class MyConstants {

   // Client ID
   public static final String GOOGLE_CLIENT_ID = "884814088321-lfgc199ui38csrv75bf2fr3etksv0kpm.apps.googleusercontent.com";

   // Client Secret
   public static final String GOOGLE_CLIENT_SECRET = "yNHBZRDB-ThCIRa29pNJEyh-";

   // Redirect URI
   public static final String GOOGLE_REDIRECT_URL = "https://examplewebsite.com/mypath/oauth2callback";

}
Google2Example.java
package org.o7planning.tutorial.scribegoogle.test;

import java.util.Scanner;

import org.o7planning.tutorial.scribegoogle.MyConstants;
import org.scribe.builder.ServiceBuilder;
import org.scribe.builder.api.Google2Api;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuthService;

public class Google2Example {

  private static final String NETWORK_NAME = "Google";

  private static final String PROTECTED_RESOURCE_URL = "https://www.googleapis.com/oauth2/v2/userinfo?alt=json";

  private static final String SCOPE = "https://mail.google.com/ https://www.googleapis.com/auth/userinfo.email";

  private static final Token EMPTY_TOKEN = null;

  public static void main(String[] args) {

      String apiKey = MyConstants.GOOGLE_CLIENT_ID;
      String apiSecret = MyConstants.GOOGLE_CLIENT_SECRET;
      String callbackUrl = MyConstants.GOOGLE_REDIRECT_URL;

 
      // Create OAuthService for Google OAuth 2.0
      OAuthService service = new ServiceBuilder().provider(Google2Api.class)
              .apiKey(apiKey).apiSecret(apiSecret).callback(callbackUrl)
              .scope(SCOPE).build();

      Scanner in = new Scanner(System.in);

      System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ===");
      System.out.println();

      Verifier verifier = null;

      Token accessToken = null;

      // Obtain the Authorization URL
      System.out.println("Fetching the Authorization URL...");
      String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN);
      System.out.println("Got the Authorization URL!");
      System.out.println("Now go and authorize Scribe here:");
      System.out.println();

 
      // Copy this URL and run in browser.
      System.out.println(authorizationUrl);
      System.out.println();

 
      // Copy Authorization Code in browser URL and paste to Console
      System.out.println("And paste the authorization code here");
      System.out.print(">>");
      verifier = new Verifier(in.nextLine());
      System.out.println();

      // Trade the Request Token and Verfier for the Access Token
      System.out.println("Trading the Request Token for an Access Token...");
      accessToken = service.getAccessToken(EMPTY_TOKEN, verifier);
      System.out.println("Got the Access Token!");
      System.out.println("(if your curious it looks like this: "
              + accessToken + " )");
      System.out.println();

      // Now let's go and ask for a protected resource!
      System.out.println("Now we're going to access a protected resource...");
      OAuthRequest request = new OAuthRequest(Verb.GET,
              PROTECTED_RESOURCE_URL);
      service.signRequest(accessToken, request);
      Response response = request.send();
      System.out.println("Got it! Lets see what we found...");
      System.out.println();
      System.out.println(response.getCode());
      System.out.println(response.getBody());

      System.out.println();
      System.out
              .println("Thats it man! Go and build something awesome with Scribe! :)");
      in.close();
  }
}
Exécutez Google2Example:
Copier URL comme les images en cercle rouge ci-dessus et l'exécutez sur le navigateur:
Après que vous vous connectez à google, Google demande au utilisateur pour permettre l'application de voir quelques informations du compte. Cliquez à Accept pour le permettre.
Le site web va réorienter (redirect) à Callback-URL. Ce URL inclut l'accès du code et vous devez copier ce code:
Copiez le code et le collez sur la fenêtre Java Console:
Vous allez recevoir des informations de l'utilisateur: