2017-10-12 17 views
12

tôi tạo thành công một Serviceclass khởi động mùa xuân để viết trên tờ google, sau khi Java Quistart Tutorial for Sheets APIGoogle sdk OAuth Sheets java trái phép sau vài giờ (khởi động mùa xuân)

Vấn đề của tôi là việc uỷ quyền không được đổi mới, vì vậy sau khi xác thực thành công đầu tiên thông qua trình duyệt, sau một vài giờ tôi nhận được 401 trái phép. Tôi làm cách nào để tự động gia hạn mã thông báo mà không cần cấp lại thông tin đăng nhập trình duyệt?

Bên dưới mã, cảm ơn trước

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:

Giải Quyết sửa đổi xây dựng của đối tượng GoogleAuthorizationCodeFlow như sau:

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

Tôi nghĩ rằng những kẻ ở https://www.draw.io có thể có cùng một vấn đề (dựa trên kinh nghiệm của tôi như là người dùng) –

+0

Am i sử dụng sai tiếp cận? Tôi đã cố gắng để kiểm tra làm thế nào để làm với Api-Key nhưng tôi đã không tìm thấy bất kỳ ví dụ – user4330585

+0

Tôi không biết câu trả lời. Tôi sẽ bắt đầu một khoản tiền thưởng cho câu hỏi này để thu hút sự chú ý của những người khác có thể biết điều đó –

Trả lời

2

Có một khái niệm mang tên refresh token và nó có vẻ như nó phù hợp với nhu cầu của bạn.

Bạn có thể tìm cũng tả trong câu hỏi này: https://stackoverflow.com/a/7209263/4988996

Edit: Theo nhận xét của bạn tôi thấy rằng google có DataStoreCredentialRefreshListener

Tiếp cận bảo vệ nguồn tài nguyên sử dụng thông tin xác thực. Mã thông báo truy cập đã hết hạn được tự động làm mới bằng cách sử dụng mã thông báo làm mới, nếu có. Đảm bảo sử dụng DataStoreCredentialRefreshListener và đặt nó cho thông tin đăng nhập bằng Credential.Builder.addRefreshListener (CredentialRefreshListener).

Checkout: 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

Cảm ơn câu trả lời của bạn, bạn có biết nếu có bất kỳ ví dụ nào sẵn sàng với google sdk java không? – user4330585

+0

Đã chỉnh sửa câu trả lời theo nhận xét của bạn. Có một cái nhìn. –

+0

@ user4330585 Bạn đã thử giải pháp này chưa? Bạn có phản hồi gì không? Tiền thưởng hết hạn hôm nay –

Các vấn đề liên quan