1

I am developing a Java based desktop application which needs to download some files from the user's Google Drive account. I have studied the Google Drive SDK documentation and so far I have come up with the following code:

public class Main
{
  public static void main(String[] args)
  {
    String clientId = "...";
    String clientSecret = "...";

    HttpTransport httpTransport = new NetHttpTransport();
    JsonFactory jsonFactory = new JacksonFactory();

    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
      httpTransport, 
      jsonFactory,
      clientId,
      clientSecret,
      Arrays.asList(DriveScopes.DRIVE)
    )
      .setAccessType("online")
      .setApprovalPrompt("auto").build();

    String redirectUri = "urn:ietf:wg:oauth:2.0:oob";     
    String url = 
      flow
        .newAuthorizationUrl()
        .setRedirectUri(redirectUri)
        .build();

    System.out.println("Please open the following URL in your browser then type the authorization code:");
    System.out.println("  " + url);
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String code = br.readLine();

    GoogleTokenResponse response = 
      flow
        .newTokenRequest(code)
        .setRedirectUri(redirectUri)
        .execute();

    GoogleCredential credential = 
      new GoogleCredential()
        .setFromTokenResponse(response);

    Drive service = 
      new Drive.Builder(httpTransport, jsonFactory, credential)
        .build();

    ...
  }
}

This works but it requires the user to authorize the application (i.e. open the given URL in a browser and copy the authorization token) each time. I need to implement the application in a way that would require the user to authorize it when he runs it for the first time only. The application would then store some kind of a secret token locally to be used the next time.

I have studied the documentation thoroughly but I haven't found any sufficient explanation about how to achieve this goal (in a desktop application particularly).

How do I do that?

Dušan Rychnovský
  • 11,699
  • 8
  • 41
  • 65

2 Answers2

3

Step 1: Generate the URL using offline access type

flow = new GoogleAuthorizationCodeFlow.Builder(
httpTransport, jsonFactory, CLIENT_ID, CLIENT_SECRET, Arrays.asList(DriveScopes.DRIVE))
.setAccessType("offline")
.setApprovalPrompt("auto").build();
String url = flow.newAuthorizationUrl().setRedirectUri(REDIRECT_URI).build();

Step 2: Store the credentials accessToken and refreshToken . code = response code for above url

GoogleTokenResponse response = flow.newTokenRequest(code).setRedirectUri(REDIRECT_URI).execute();
GoogleCredential credential = new GoogleCredential.Builder().setTransport(httpTransport)
                .setJsonFactory(jsonFactory)
                .setClientSecrets(CLIENT_ID, CLIENT_SECRET)
                .build()
                .setFromTokenResponse(response);
String accessToken = credential.getAccessToken();
String refreshToken = credential.getRefreshToken();

Step 3: Reuse tokens when needed

GoogleCredential credential1 = new GoogleCredential.Builder().setJsonFactory(jsonFactory)
     .setTransport(httpTransport).setClientSecrets(CLIENT_ID, CLIENT_SECRET).build();
credential1.setAccessToken(accessToken);
credential1.setRefreshToken(refreshToken);
Drive service = new Drive.Builder(httpTransport, jsonFactory, credential1).build();

Step 4: Understand OAuth to handle errors and refreshing of the tokens

Vinay Sheshadri
  • 361
  • 4
  • 13
0

At http://javadoc.google-api-java-client.googlecode.com/hg/1.7.0-beta/jdiff/Google%20API%20Client%20Library%20for%20Java%201.7.0-beta/com/google/api/client/googleapis/auth/oauth2/GoogleAuthorizationCodeFlow.html read about accessType = "offline". This will return a Refresh Token, which is the storable "secret token" that you're looking for. Save this and you can convert it to an Auth Token without any user intervention.

pinoyyid
  • 21,499
  • 14
  • 64
  • 115
  • Could you please be more specific about how do I update the code? I cannot seem to get it working. Thanks in advance! – Dušan Rychnovský Sep 14 '13 at 15:44
  • add .setAccessType("offline") in your flow...build. There is an example here http://stackoverflow.com/questions/10294124/getting-null-refresh-token . Alternatively you could just call the URLs directly as described here https://developers.google.com/accounts/docs/OAuth2InstalledApp – pinoyyid Sep 14 '13 at 16:06
  • And why would you have the user open a browser url and copy the token? Why not urlfetch it? – Zig Mandel Sep 14 '13 at 16:32
  • @ZigMandel I don't understand what you mean by urlfetching the token. Could you please explain it? – Dušan Rychnovský Sep 14 '13 at 17:42
  • See the google oauth docs on client type flow. There are examples there. – Zig Mandel Sep 15 '13 at 03:45