Google Sheets java sdk oAuth在数小时后未经授权(春季启动)
我成功地创建了一个springbootserviceclass,以便在googlesheets上进行写操作 我的问题是授权没有更新,所以在第一次通过浏览器成功进行身份验证后,几个小时后我得到了401未授权。 如何在不重新发布浏览器登录的情况下自动续订令牌 下面的代码,提前感谢Google Sheets java sdk oAuth在数小时后未经授权(春季启动),java,spring-boot,google-sheets-api,Java,Spring Boot,Google Sheets Api,我成功地创建了一个springbootserviceclass,以便在googlesheets上进行写操作 我的问题是授权没有更新,所以在第一次通过浏览器成功进行身份验证后,几个小时后我得到了401未授权。 如何在不重新发布浏览器登录的情况下自动续订令牌 下面的代码,提前感谢 import com.google.api.client.auth.oauth2.Credential; import com.google.api.client.extensions.java6.auth.oauth2.
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;
}
}
有一个名为刷新令牌的概念,它似乎适合您的需要 你可以在这个问题中找到很好的描述: 编辑:根据你的评论,我发现谷歌有DataStoreCredentialRefreshListener 使用凭据访问受保护的资源。如果适用,将使用刷新令牌自动刷新过期的访问令牌。确保使用DataStoreCredentialRefreshListener,并使用credential.Builder.addRefreshListener(CredentialRefreshListener)为凭据设置它 结帐:
static void addDataStoreCredentialRefreshListener(
Credential.Builder credentialBuilder,字符串userId,DataStoreFactory(DataStoreFactory)
抛出IOException{
credentialBuilder.addRefreshListener(
新的DataStoreCredentialRefreshListener(userId,dataStoreFactory));
}
我认为,在上的人可能有同样的问题(根据我作为用户的经验),我是否使用了错误的方法?我试图检查如何使用Api密钥,但没有找到任何示例我不知道答案。我将在这个问题上开始悬赏,以获得其他可能知道它的人的更多关注。在第一次尝试中,我实际上是ge4tting 401无人看管…我如何才能确保我得到了正确的JSON文件?谢谢你的回答,你知道google sheets java sdk是否提供了任何示例?根据你的评论编辑了答案。看看。@user4330585您尝试过这个解决方案吗?有什么反馈吗?悬赏期满today@user4330585我没有时间尝试这些。答案看起来并不完美,但我可能会奖励奖金,因为这是最好的答案。我把它作为可接受的答案检查了一下。我不得不在GoogleAuthorizationCodeFlow的he构建上添加一个修改,但是这个答案帮助我找到了解决方案。谢谢!
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();