2017-10-12 1 views
12

ich erfolgreich eine Feder Boot Serviceclass, um auf Google Blätter, nach den Java Quistart Tutorial for Sheets APIGoogle Sheets java sdk oAuth unbefugter nach einigen Stunden (Feder-Boot)

Mein Problem ist, zu schreiben erstellt, dass die Zulassung nicht erneuert, so dass nach die erste erfolgreiche Authentifizierung per Browser, nach einigen Stunden bekomme ich 401 nicht mehr autorisiert. Wie kann ich den Token automatisch erneuern, ohne die Browseranmeldung erneut zu erteilen?

Unter dem Code, danke im voraus

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.extensions.jetty.auth.oauth2.LocalServerReceiver.Builder; 
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow; 
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets; 
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; 
import com.google.api.client.http.HttpTransport; 
import com.google.api.client.json.JsonFactory; 
import com.google.api.client.json.jackson2.JacksonFactory; 
import com.google.api.client.util.store.FileDataStoreFactory; 
import com.google.api.services.sheets.v4.Sheets; 
import com.google.api.services.sheets.v4.SheetsScopes; 
import com.google.api.services.sheets.v4.model.AppendValuesResponse; 
import com.google.api.services.sheets.v4.model.ValueRange; 

@Service 
public class GoogleSheetsServiceImpl implements GoogleSheetsService { 

    private static final Log LOGGER = LogFactory.getLog(GoogleSheetsServiceImpl.class); 

    /** Application name. */ 
    @Value("${google-sheets.application-name}") 
    private String applicationName; 

    /** 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/sheets.googleapis.com-orders"); 

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

    /** Global instance of the JSON factory. */ 
    private JsonFactory jsonFactory; 

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

    /** 
    * Global instance of the scopes required by this quickstart. 
    * 
    * If modifying these scopes, delete your previously saved credentials at 
    * ~/.credentials/sheets.googleapis.com-java-quickstart 
    */ 
    private List<String> scopes; 

    /** Sheet service. */ 
    private Sheets sheetsService; 

    public GoogleSheetsServiceImpl() throws Throwable { 
     // init 
     try { 
      this.jsonFactory = JacksonFactory.getDefaultInstance(); 
      this.scopes = Arrays.asList(SheetsScopes.SPREADSHEETS); 
      this.httpTransport = GoogleNetHttpTransport.newTrustedTransport(); 
      this.dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR); 
     } catch (Throwable t) { 
      LOGGER.error("Error on init Google Sheets Service: " + t.getMessage()); 
      throw t; 
     } 

     // get sheet service 
     Credential credential = this.authorize(); 
     this.sheetsService = new Sheets.Builder(this.httpTransport, this.jsonFactory, credential) 
       .setApplicationName(this.applicationName).build(); 
    } 

    public void appendValueRangeToGoogleSheet(String spreadsheetId, String range, ValueRange valueRange) 
      throws IOException { 

     // append line 
     Sheets.Spreadsheets.Values.Append request = sheetsService.spreadsheets().values() 
       .append(spreadsheetId, range, valueRange).setValueInputOption("RAW"); 
     AppendValuesResponse response = request.execute(); 
    } 

    /** 
    * Creates an authorized Credential object. 
    * 
    * @return an authorized Credential object. 
    * @throws IOException 
    */ 
    private Credential authorize() throws IOException { 
     // Load client secrets. 
     InputStream in = GoogleSheetsServiceImpl.class.getResourceAsStream("/google_sheets/client_secret.json"); 
     GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(this.jsonFactory, new InputStreamReader(in)); 

     // Build flow and trigger user authorization request. 
     GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(this.httpTransport, this.jsonFactory, 
       clientSecrets, this.scopes).setDataStoreFactory(this.dataStoreFactory).setAccessType("online").build(); 
     LocalServerReceiver.Builder localServerReceiverBuilder = new Builder(); 
     localServerReceiverBuilder.setHost("localhost"); 
     localServerReceiverBuilder.setPort(46228); 
     Credential credential = new AuthorizationCodeInstalledApp(flow, localServerReceiverBuilder.build()) 
       .authorize("user"); 
     LOGGER.info("Credentials saved to " + DATA_STORE_DIR.getAbsolutePath()); 
     return credential; 
    } 

} 

Edit:

Löste das Build von GoogleAuthorizationCodeFlow Objekt wie folgt ändern:

GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(this.httpTransport, this.jsonFactory, 
      clientSecrets, this.scopes).setDataStoreFactory(this.dataStoreFactory).setAccessType("offline") 
        .setApprovalPrompt("force") 
        .addRefreshListener(
          new DataStoreCredentialRefreshListener(credentialUserId, this.dataStoreFactory)) 
        .build(); 
+0

Ich denke, die Jungs bei https://www.draw.io könnte das gleiche Problem haben (basierend auf meiner Erfahrung als Benutzer) –

+0

verwende ich die falsche Ansatz? Ich habe versucht, zu überprüfen, wie mit Api-Key zu tun, aber ich habe kein Beispiel gefunden – user4330585

+0

Ich weiß nicht die Antwort. Ich werde ein Kopfgeld auf diese Frage starten, um mehr Aufmerksamkeit von anderen Leuten zu bekommen, die es vielleicht wissen –

Antwort

2

Es ist ein Konzept, Aktualisierungs-Token genannt und es scheint, als ob es Ihren Bedürfnissen entspricht.

Sie können in dieser Frage gut Discribe finden: https://stackoverflow.com/a/7209263/4988996

Edit: Nach Ihrem Kommentar fand ich, dass Google DataStoreCredentialRefreshListener

Zugriff auf geschützte Ressourcen unter Verwendung des Credential hat. Abgelaufene Zugriffstoken werden ggf. automatisch mit dem Aktualisierungstoken aktualisiert. Stellen Sie sicher, dass Sie DataStoreCredentialRefreshListener verwenden und für die Berechtigung mithilfe von Credential.Builder.addRefreshListener (CredentialRefreshListener) festlegen.

Kasse: https://developers.google.com/api-client-library/java/google-oauth-java-client/oauth2

static void addDataStoreCredentialRefreshListener( Credential.Builder credentialBuilder, String userId, DataStoreFactory dataStoreFactory) throws IOException { credentialBuilder.addRefreshListener( new DataStoreCredentialRefreshListener(userId, dataStoreFactory)); }

+1

Danke für Ihre Antwort, wissen Sie, ob es ein Beispiel gibt, das mit Google Blättern java sdk bereit ist? – user4330585

+0

Bearbeitete die Antwort entsprechend Ihrem Kommentar. Guck mal. –

+0

@ user4330585 Haben Sie diese Lösung ausprobiert? Irgendeine Anregung? Das Kopfgeld läuft heute –