0

My project is a java spark project that I have hosted on heroku. A part of the project requires that I download a particular file from my google drive into the application. I managed to set up everything when my application was running locally but as soon as I deployed the app it stopped working. This was regardless of the fact that when the app was running locally I used an Oauth2 client ID of type other and when I deployed the application I created a new one of type web application.

Below is a snippet of the authentication and download code:

public class AutoCalls {

    /** Application name. */
    private static final String APPLICATION_NAME = "calls-made";
    private static final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("target/classes/auth"), ".credentials/calls-made");
    private static FileDataStoreFactory DATA_STORE_FACTORY;
    private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
    private static HttpTransport HTTP_TRANSPORT;
    private static final List<String> SCOPES = Arrays.asList(DriveScopes.DRIVE);

    static {
        try {
            HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
            DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);

        } catch (GeneralSecurityException | IOException t) {
            System.exit(1);
        }
    }

    public static void startDownload() throws IOException, ParseException {

        Drive serv = getDriveService();
     // drive stuff deleted
    }

    public static Credential authorize() throws IOException {
        InputStream in = new FileInputStream("target/classes/auth/client_secret_*****************************************.apps.googleusercontent.com.json");
        GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
        GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
            .setDataStoreFactory(DATA_STORE_FACTORY)
            .setAccessType("offline")
            .build();
        Credential credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
        System.out.println("Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
        return credential;
    }

    public static Drive getDriveService() throws IOException {
        Credential credential = authorize();

        return new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
            .setApplicationName(APPLICATION_NAME)
            .build();
    }
}

Currently when I try to initiate the download I get a URL in the Heroku logs a follows:

2017-02-20T10:32:28.656820+00:00 app[web.1]: Please open the following address in your browser:
2017-02-20T10:32:28.656908+00:00 app[web.1]:   https://accounts.google.com/o/oauth2/auth?access_type=offline&client_id=************-vvdi7u6bmp1vc90sdidtnuiftdi1t49c.apps.googleusercontent.com&redirect_uri=http://localhost:48085/Callback&response_type=code&scope=https://www.googleapis.com/auth/drive

When I try open the URL in a browser I get an error:

Error: redirect_uri_mismatch

I cannot find any good step by step tutorial on accessing google drive contents on a java web application so any help would be arreiciated.

pinoyyid
  • 21,499
  • 14
  • 64
  • 115
Chognificent
  • 393
  • 6
  • 20

1 Answers1

0

Generally, if OAuth works on server-A but not on server-B, it's because the redirect URL hasn't been configured correctly on the API Console. There is no reason why you would need to use a different client-ID because a single client-ID can be configured with multiple URLs, eg your local host and your heroku server. Another possibility is the use of https.

There is a separate problem in your code where you iterate on lista.isEmpty(). You should be iterating on nextPageToken != null. See the answer to Google drive rest API, Download files from root folder only

Community
  • 1
  • 1
pinoyyid
  • 21,499
  • 14
  • 64
  • 115
  • Does the fact that I was running the application locally then moved it to Heroku not have an implication? I ask because client IDs can be for web applications and other (for desktop applications, which does not have redirect URLs for example) etc. The Client ID that was working was of type other and therefore did not accept redirect URLs. – Chognificent Feb 20 '17 at 19:48
  • I don't understand why you changed the client type. Surely your application should be the same in testing as it is in production. So the standard approach is simply to have a single client ID with redirect URLs for both your test environment and your production environment. Either I've misunderstood what you are trying to achieve, or you've misunderstood OAuth/client types somewhere along the way. – pinoyyid Feb 20 '17 at 21:58
  • I changed my client type because the one i was using (other) which does not allow for a redirect URL and therefore was not working. – Chognificent Feb 22 '17 at 11:24
  • it sounds like you haven't quite understood OAuth and the auth flow. I suggest take a step back and do a bit of reading. – pinoyyid Feb 22 '17 at 16:21