2012-12-08 82 views
14

我正在開發一個應用程序,該應用程序使用OAuth2和谷歌客戶端庫訪問Google API(以Calendar API開始)(位於Appengine和GWT上) BTW)。如何獲得離線令牌和刷新令牌並自動刷新對Google API的訪問

我已經實現了我的OAuth2Call後端servlet,擴展了Google AbstractAppEngineAuthorizationCodeCallbackServlet

我有工作,我可以訪問並可以查看日曆等,但有兩個問題:

1)我沒有得到一個刷新令牌,儘管明確請求離線訪問:

public static GoogleAuthorizationCodeFlow newFlow(String scope) throws IOException { 
    GoogleAuthorizationCodeFlow.Builder builder = new GoogleAuthorizationCodeFlow.Builder(
      HTTP_TRANSPORT, 
      JSON_FACTORY, 
      getClientSecrets(), 
      Collections.singleton(scope)); 

    builder.setCredentialStore(new AppEngineCredentialStore()).setAccessType("offline"); 

    return builder.build(); 
} 

2)我看不到如何設置自動刷新功能。 這些頁面描述的方法:

,但我看不到的地方添加刷新監聽器。有在GoogleAuthorizationCodeFlow.Builder類中沒有這樣的方法,不同的是Credential.Builder

編輯 調試代碼更後,當憑證回來(在onSuccess()法)似乎有RefreshListener組已經.....所以也許這是他們的默認情況,我唯一的問題是我沒有得到refresh_token,儘管要求。

也許還需要查看Google API控制檯中的設置嗎?

回答

16

你應該注意一件事:只有當用戶明確表示同意請求的作用域時,纔會返回刷新標記(除了訪問標記)。基本上,顯示批准頁面時。所有後續流程將只返回訪問令牌。

現在,爲了測試您的應用程序並確保您第一次收到刷新令牌,您可以使用approval_prompt = force參數(builder.setApprovalPrompt("force"))確保審批頁面顯示在流程中,並且您獲得用戶的明確同意。解決任何問題並確保刷新令牌存儲正確後,可以刪除該標誌(默認值爲auto

在開發人員指南中的offline access section中也提供了更多信息。

+0

感謝您的評論,我會檢查這些行。目前,我做了一個明確的令牌撤銷,然後再次請求它,我總是通過顯式接受屏幕爲用戶 - 但仍然沒有得到一個refresh_token。 –

+0

vlatko,我正在做你說的所有事情*除了*迅速的力量,這似乎已經修復它!所以,你的回答非常感謝!這是一個錯誤,還是(太廣泛的)文檔中的明顯遺漏? –

0

我看着這個,並得出結論,access_token只需要使用一次。也就是說,每一個谷歌查詢過程分爲兩個步驟:

  1. 使用refresh_token生成一個臨時的access_token
  2. 使用的access_token爲您的操作所需的一個或多個查詢。

我在這裏看到了一些關於確保服務器時鐘同步的帖子。但這似乎是不必要的複雜性。

對於更詳細的解釋:http://www.tqis.com/eloquency/googlecalendar.htm

+0

謝謝陽光。但問題是,在第一次授權時,我得到了AccessToken,但不是RefreshToken,儘管通過將AccessType設置爲「脫機」來請求它。如果您使用Google類(一旦您擁有RefreshToken),他們將存儲它並使用它在到期時自動獲取新的AccessToken,這一切對您都是透明的。 –

4

要獲得刷新令牌,你必須既存取類型=「離線」和approvalPrompt =「力」進行設置。

GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, 
       JSON_FACTORY, CLIENT_ID, CLIENT_SECRET, SCOPE).setAccessType("offline").setApprovalPrompt("force").build(); 
+0

好的,謝謝你! .setApprovalPrompt(..)必須是一個相對較新的要求。我有我的代碼工作大約一個月或兩個月前沒有這個選項,它給我刷新令牌。突然之間,它停止了工作,我只是想知道爲什麼。 – ThaDon