0

我使用以下代碼將文件上傳到谷歌驅動器,它用於基於Java的Web應用程序。一切工作正常,除了認證。Google Drive API Java認證僅適用於第一次

代碼的主要問題是,它只要求一次認證,稍後再運行項目時,它從不要求認證。

我希望驗證客戶端提出的每個請求。

/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package myapp.util; 

import com.google.api.client.auth.oauth2.Credential; 
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp; 
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver; 
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow; 
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets; 
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; 
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; 
import com.google.api.client.googleapis.media.MediaHttpUploader; 
import com.google.api.client.googleapis.media.MediaHttpUploaderProgressListener; 
import com.google.api.client.http.HttpTransport; 
import com.google.api.client.http.InputStreamContent; 
import com.google.api.client.json.jackson2.JacksonFactory; 
import com.google.api.client.json.JsonFactory; 
import com.google.api.client.util.store.FileDataStoreFactory; 

import com.google.api.services.drive.DriveScopes; 
import com.google.api.services.drive.model.*; 
import com.google.api.services.drive.Drive; 
import java.io.BufferedInputStream; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 

import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.URLDecoder; 
import java.security.GeneralSecurityException; 
import java.util.Arrays; 
import java.util.List; 
import javax.faces.context.FacesContext; 
import javax.servlet.ServletContext; 

public class GDrive { 

    /** 
    * Application name. 
    */ 
    private static final String APPLICATION_NAME 
      = "Drive API Java Quickstart"; 

    /** 
    * Directory to store user credentials for this application. 
    */ 
    private static final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"), ".credentials/drive-java-quickstart.json"); 

    /** 
    * Global instance of the {@link FileDataStoreFactory}. 
    */ 
    private static FileDataStoreFactory DATA_STORE_FACTORY; 

    /** 
    * Global instance of the JSON factory. 
    */ 
    private static final JsonFactory JSON_FACTORY 
      = JacksonFactory.getDefaultInstance(); 

    /** 
    * Global instance of the HTTP transport. 
    */ 
    private static HttpTransport HTTP_TRANSPORT; 

    /** 
    * Global instance of the scopes required by this quickstart. 
    * 
    * If modifying these scopes, delete your previously saved credentials at 
    * ~/.credentials/drive-java-quickstart 
    */ 
    private static final List<String> SCOPES 
      = Arrays.asList(DriveScopes.DRIVE_FILE); 

    static { 
     try { 
      HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport(); 
      DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR); 
     } catch (Throwable t) { 
      t.printStackTrace(); 
      System.exit(1); 
     } 
    } 

    /** 
    * Creates an authorized Credential object. 
    * 
    * @return an authorized Credential object. 
    * @throws IOException 
    */ 
    public static Credential authorize() throws IOException { 
     ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext(); 
     String basePath = servletContext.getRealPath(""); 
     basePath = URLDecoder.decode(basePath, "UTF-8"); 
     // Load client secrets. 
     InputStream in = new FileInputStream(
       new java.io.File(basePath + "/resources/client_secret.json")); 
     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(DATA_STORE_FACTORY) 
       .setAccessType("offline") 
       .setApprovalPrompt("auto") 
       .build(); 

     GoogleCredential credential = new GoogleCredential(); 
     System.out.println(
       "Credentials saved to " + DATA_STORE_DIR.getAbsolutePath()); 
     return credential; 
    } 

    /** 
    * Build and return an authorized Drive client service. 
    * 
    * @return an authorized Drive client service 
    * @throws IOException 
    */ 
    public static Drive getDriveService() throws IOException { 
     Credential credential = authorize(); 
     System.out.println("getAccessToken" + credential.getAccessToken()); 

     System.out.println("setAccessToken" + credential.getAccessToken()); 
     System.out.println("setExpiresInSeconds" + credential.getExpiresInSeconds()); 

     System.out.println("setRefreshToken" + credential.getRefreshToken()); 
     return new Drive.Builder(
       HTTP_TRANSPORT, JSON_FACTORY, credential) 
       .setApplicationName(APPLICATION_NAME) 
       .build(); 
    } 

    public boolean uploadToDrive(String filePathUrl, String fileName) throws FileNotFoundException, IOException, GeneralSecurityException, Exception { 
     Drive service = GDrive.getDriveService(); 
     boolean status = false; 
     // TODO code application logic here 
     java.io.File mediaFile = new java.io.File(filePathUrl); 
     com.google.api.services.drive.model.File fileMetadata = new com.google.api.services.drive.model.File(); 
     fileMetadata.setName(fileName); 
     InputStreamContent mediaContent = new InputStreamContent("application/octet-stream", new BufferedInputStream(new FileInputStream(mediaFile))); 
     mediaContent.setLength(mediaFile.length()); 

     HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport(); 

     Drive.Files.Create request = service.files().create(fileMetadata, mediaContent); 
     request.getMediaHttpUploader().setProgressListener(new CustomProgressListener()); 
     request.execute(); 
     status = true; 
     return status; 
    } 

} 

class CustomProgressListener implements MediaHttpUploaderProgressListener { 

    public void progressChanged(MediaHttpUploader uploader) throws IOException { 
     switch (uploader.getUploadState()) { 
      case INITIATION_STARTED: 
       System.out.println("Initiation has started!"); 
       break; 
      case INITIATION_COMPLETE: 
       System.out.println("Initiation is complete!"); 
       break; 
      case MEDIA_IN_PROGRESS: 
       System.out.println(uploader.getProgress()); 
       break; 
      case MEDIA_COMPLETE: 
       System.out.println("Upload is complete!"); 
     } 
    } 
} 
+0

在setDataStoreFactory(DATA_STORE_FACTORY)中做過。我的猜測是控制它。 – DaImTo

+0

你可以在代碼中看到,我已經爲GoogleAuthorizationCodeFlow設置了數據存儲工廠 –

+1

FileDataStoreFactory可能是保存身份驗證的一些地方。一旦你的身份證可以保存在你的硬盤上。您需要弄清楚如何告訴它它是一個不同的用戶或使用不同的數據存儲。 https://developers.google.com/api-client-library/java/google-http-java-client/reference/1.20.0/com/google/api/client/util/store/FileDataStoreFactory – DaImTo

回答

1

通過設計,客戶端庫存儲授權信息,以便每次運行應用程序時都不會提示用戶。客戶端庫將授權信息保存到您提供的DataStore實例中,在您的案例中爲FileDataStore,該文件將文件存儲在特定目錄中。

多個用戶可以共享相同的數據存儲,但在執行授權時您需要傳遞唯一的用戶標識。對於已安裝的應用程序,這在AuthorizationCodeInstalledApp.authorize中完成,對於Web應用程序,它通過覆蓋AbstractAuthorizationCodeServlet.getUserIdAbstractAuthorizationCodeCallbackServlet.getUserId完成。有關更多信息和示例,請參閱Java客戶端庫的OAuth2 guide