我对 GoogleAuthorizationCodeFlow ( Java ) 有疑问。我正在尝试使用 Google 的“OAuth 2.0 for Web Server Applications”为我的 Web 项目建立 Google Calender 连接。因此,您可以使用 Google 的 Java api 库。
我使用 Google 的 AuthorizationCallbackServlet 来接收访问和刷新令牌。
GoogleAuthorizationCodeFlow 将创建的凭据与 GoogleAuthorizationCodeFlow 及其 JdoCredentialStore 一起保存。作为一个 JDO 实现,我正在使用 DataNucleus。
static PersistenceManagerFactory pmf;
static{
Properties properties = new Properties();
properties.setProperty("javax.jdo.PersistenceManagerFactoryClass",
"org.datanucleus.api.jdo.JDOPersistenceManagerFactory");
properties.setProperty("javax.jdo.option.ConnectionDriverName","com.mysql.jdbc.Driver");
properties.setProperty("javax.jdo.option.ConnectionURL","jdbc:mysql://localhost:3306/rssparsetest");
properties.setProperty("javax.jdo.option.ConnectionUserName","root");
properties.setProperty("javax.jdo.option.ConnectionPassword","root");
pmf = JDOHelper.getPersistenceManagerFactory(properties);
}
public static CredentialStore JDO_CREDENTIAL_STORE = new JdoCredentialStore(pmf);
public static AuthorizationCodeFlow AUTHORIZATION_CODE_FLOW = getNewAuthorizationCodeFlow();
public static AuthorizationCodeFlow getNewAuthorizationCodeFlow(){
return new GoogleAuthorizationCodeFlow.Builder(Constants.HTTP_TRANSPORT, Constants.JSON_FACTORY,
Constants.CLIENT_ID, Constants.CLIENT_SECRET,
Collections.singleton(CalendarScopes.CALENDAR)).setCredentialStore(Constants.JDO_CREDENTIAL_STORE).setAccessType("offline")
.build();
}
无状态 Bean 中的用法:
public List<CalendarListEntry> getCalendarList() {
Credential credential = null;
AuthorizationCodeFlow authCodeFlow = Constants.getNewAuthorizationCodeFlow();
try {
credential = authCodeFlow.loadCredential("USERID");
} catch (Exception e) {
//...
}
一切工作正常(我能够列出我的日历条目,凭据保存在我的 MySQL 数据库中) ,除了使用持久刷新令牌(GoogleAuthorizationCodeFlow 所做的)来引用访问令牌的时候。
Caused by: javax.jdo.JDODataStoreException: Duplicate entry 'USERID' for key 'PRIMARY'
NestedThrowables:
java.sql.BatchUpdateException: Duplicate entry 'USERID' for key 'PRIMARY'
at org.datanucleus.api.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:421)
at org.datanucleus.api.jdo.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManager.java:735)
at org.datanucleus.api.jdo.JDOPersistenceManager.makePersistent(JDOPersistenceManager.java:755)
at com.google.api.client.extensions.jdo.auth.oauth2.JdoCredentialStore.store(JdoCredentialStore.java:47)
总结一下,我可以
- 使用 accessToken 和 refreshToken 接收并保存 Credential
- 列出日历条目(只要访问令牌的时间没有过期)
如果没有获得“javax.jdo.JDODataStoreException: Duplicate entry ' USERID ' for key 'PRIMARY'”异常,我无法使用 GoogleAuthorizationCodeFlow刷新我的访问令牌。
我究竟做错了什么?
非常感谢您的帮助!