Search code examples
javaspring-bootgoogle-drive-apigoogle-api-java-client

Google drive API store credentials for java


I am developing a spring-boot application that needs to upload files to a Google Drive account. I found a thread for storing the access_token, and refresh token, but was deprecated, here is the link: How to store credentials for Google Drive SDK locally. Is there a way using v3 to implement google drive authentication once, and refresh the access token when needed?

Below is a service that upload files to drive

@Service
public class GoogleDriveService {
    private static final String baseConfigPath = "/config.json";

    private static final String APPLICATION_NAME = "application name";
    private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
    private static final String TOKENS_DIRECTORY_PATH = "tokens";

    private static final List<String> SCOPES = Collections.singletonList(DriveScopes.DRIVE);
    private static final String CREDENTIALS_FILE_PATH = "/client_secret.json";

    /////////////////////////////////////////////////////////////////////////////////////////

    public static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
        // Load client secrets.
        InputStream in = GoogleDriveClient.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
        if (in == null) {
            throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
        }
        GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));

        // Build flow and trigger user authorization request.
        GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
                HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
                .setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
                .setAccessType("offline")
                .build();


        LocalServerReceiver receiver = new LocalServerReceiver.Builder().setHost("127.0.0.1").setPort(8089).build();
        return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
    }


    public boolean uploadGoogleDriveFile(java.io.File originalFile){

        final NetHttpTransport HTTP_TRANSPORT;
        try {
            HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
            Drive service = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
                    .setApplicationName(APPLICATION_NAME)
                    .build();

            File file = new File();
            file.setName(originalFile.getName());

            FileContent content = new FileContent("text/plain", originalFile);

            File uploadedFile  = service.files().create(file, content).setFields("id").execute();
            System.out.println("File ID: " + uploadedFile.getId());

            return true;
        } catch (GeneralSecurityException | IOException e) {
            e.printStackTrace();
            return false;
        }
    }
}

Solution

  • Something like this should be what you are looking for it should store the creds for you for the user.

    /**
     * A simple example of how to access the Google Drive API.
     */
    public class HelloDrive {
      // Path to client_secrets.json file downloaded from the Developer's Console.
      // The path is relative to HelloDrive.java.
      private static final String CLIENT_SECRET_JSON_RESOURCE = "client_secrets.json";
    
      // Replace with your view ID.
      private static final String VIEW_ID = "<REPLACE_WITH_VIEW_ID>";
    
          // The directory where the user's credentials will be stored.
          private static final File DATA_STORE_DIR = new File(
              System.getProperty("user.home"), ".store/hello_drive");
        
          private static final String APPLICATION_NAME = "Hello Google drive";
          private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
          private static NetHttpTransport httpTransport;
          private static FileDataStoreFactory dataStoreFactory;
        
          public static void main(String[] args) {
            try {
              Drive service = initializeDrive();
        
              
            } catch (Exception e) {
              e.printStackTrace();
            }
          }
       /**
       * Initializes an authorized Drive service object.
       *
       * @return The Drive service object.
       * @throws IOException
       * @throws GeneralSecurityException
       */
      private static Drive initializeDrive() throws GeneralSecurityException, IOException {
    
        httpTransport = GoogleNetHttpTransport.newTrustedTransport();
        dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
    
        // Load client secrets.
        GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY,
            new InputStreamReader(HelloDrive.class
                .getResourceAsStream(CLIENT_SECRET_JSON_RESOURCE)));
    
        // Set up authorization code flow for all authorization scopes.
        GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow
            .Builder(httpTransport, JSON_FACTORY, clientSecrets,
                DriveScopes.all()).setDataStoreFactory(dataStoreFactory)
            .build();
    
        // Authorize.
        Credential credential = new AuthorizationCodeInstalledApp(flow,
            new LocalServerReceiver()).authorize("user");
        // Construct the Drive service object.
        return new Drive.Builder(httpTransport, JSON_FACTORY, credential)
            .setApplicationName(APPLICATION_NAME).build();
      }
    

    Based upon the Google Analtyics sample