gpt4 book ai didi

java - 几个小时后,Google 表格 java sdk oAuth 未经授权( Spring 启动)

转载 作者:搜寻专家 更新时间:2023-10-30 21:12:34 26 4
gpt4 key购买 nike

我成功地创建了一个 spring boot Serviceclass 以便在 google 表格上写,遵循 Java Quistart Tutorial for Sheets API

我的问题是授权没有更新,所以在第一次通过浏览器成功验证后,几个小时后我得到 401 unauthorized。如何在不重新发布浏览器登录的情况下自动更新 token ?

下面是代码,在此先感谢

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;
}

}

编辑:

解决了如下修改 GoogleAuthorizationCodeFlow 对象的构建问题:

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();

最佳答案

有一个概念叫做refresh token,看起来很适合你的需求。

你可以在这个问题中找到很好的描述: https://stackoverflow.com/a/7209263/4988996

编辑:根据您的评论,我发现谷歌有 DataStoreCredentialRefreshListener

Access protected resources using the Credential. Expired access tokens are automatically refreshed using the refresh token, if applicable. Make sure to use DataStoreCredentialRefreshListener and set it for the credential using Credential.Builder.addRefreshListener(CredentialRefreshListener).

结帐: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));
}

关于java - 几个小时后,Google 表格 java sdk oAuth 未经授权( Spring 启动),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46705204/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com