2012-09-18 43 views
11

我已經成功安裝並運行了Google Drive Quick Start application called DriveCommandLine。我也調整了一下,以獲取我雲端硬盤帳戶中某個文件的文件信息。Google Drive/OAuth - 無法弄清楚如何獲得可重複使用的GoogleCredentials

我現在想要做的是以某種方式保存證書並重新使用它們,而不必每次都訪問網頁以獲取授權碼。我已檢出this page,其中包含檢索和使用OAuth 2.0憑據的說明。爲了使用該實施例類(MyClass的),我已經修改在DriveCommandLine線,其中Credential對象被實例化:

Credential credential = MyClass.getCredentials(code, ""); 

這導致以下拋出異常:

java.lang.NullPointerException 
    at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:187) 
    at com.google.api.client.json.jackson.JacksonFactory.createJsonParser(JacksonFactory.java:84) 
    at com.google.api.client.json.JsonFactory.fromInputStream(JsonFactory.java:247) 
    at com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets.load(GoogleClientSecrets.java:168) 
    at googledrive.MyClass.getFlow(MyClass.java:145) 
    at googledrive.MyClass.exchangeCode(MyClass.java:166) 
    at googledrive.MyClass.getCredentials(MyClass.java:239) 
    at googledrive.DriveCommandLine.<init>(DriveCommandLine.java:56) 
    at googledrive.DriveCommandLine.main(DriveCommandLine.java:115) 

I」我們一直在研究這些API(Google Drive和OAuth)2天,並且取得的進展甚微。我非常感謝上述錯誤以及總體持久性憑證的問題。

這整個結構似乎對我來說是不必要的複雜。任何人都想解釋爲什麼我不能通過傳遞我的Google用戶名和密碼來創建一個簡單的Credential對象?

感謝, 布賴恩·卡羅爾Ø愛爾蘭都柏林

*更新*

好吧,我剛剛得到周圍上面的錯誤,我現在有一個新的。

我解決第一個問題的方法是修改MyClass.getFlow()。而不是創建從JSON文件GoogleClientServices的對象,我使用了一個不同版本的GoogleAuthorizationCodeFlow.Builder的,可以讓你直接進入客戶端ID和客戶端密鑰爲字符串:

flow = new GoogleAuthorizationCodeFlow.Builder(httpTransport, jsonFactory, "<MY CLIENT ID>", "<MY CLIENT SECRET>", SCOPES).setAccessType("offline").setApprovalPrompt("force").build(); 

我現在已經是問題我收到以下錯誤,當我嘗試使用流(GoogleAuthorizationCodeFlow對象)來交換授權代碼證書對象:

An error occurred: com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request 
{ 
    "error" : "invalid_scope" 
} 
googledrive.MyClass$CodeExchangeException 
     at googledrive.MyClass.exchangeCode(MyClass.java:185) 
     at googledrive.MyClass.getCredentials(MyClass.java:262) 
     at googledrive.DriveCommandLine.<init>(DriveCommandLine.java:56) 
     at googledrive.DriveCommandLine.main(DriveCommandLine.java:115) 

有,我應該使用一些這方面的其他範圍是什麼?我目前正在使用MyClass提供的示波器陣列:

private static final List<String> SCOPES = Arrays.asList(
     "https://www.googleapis.com/auth/drive.file", 
     "https://www.googleapis.com/auth/userinfo.email", 
     "https://www.googleapis.com/auth/userinfo.profile"); 

謝謝!

回答

13

我感到你的痛苦。我已經兩個月了,但仍然感到驚訝。

我的一些學習收穫的......

  • 當您要求的用戶權限,指定 「離線=真」。這將(「有時」原文)返回一個refreshtoken,這與具有受限權限的密碼一樣好。您可以隨時存儲並重復使用它(直到用戶撤銷它)來獲取訪問令牌。

  • 我的感覺是,Google SDKs更像是一種無助的幫助。我一個接一個地停止使用它們,現在直接調用REST API。

  • 就最後一點而言,您可以(僅)使用Google clientlogin協議訪問上一代API。然而,這是完全不贊同的,很快就會被關閉。 OAuth旨在對本質上覆雜的授權進行細粒度控制。所以儘管我認爲這很複雜,但我認爲這不必要。我們生活在一個複雜的世界:-)

你的和我的經驗表明,發展社會仍然需要一個統一的文件和配方來獲得這些東西到我們的後視鏡這樣我們可以專注於手頭的任務。

+0

感謝pinoyyid,對不起,我不小心添加編輯/更新到您的文章,而不是我自己。我仍然習慣張貼在這裏!我會嘗試實施你的建議,並讓你知道這是怎麼回事。 PS - 不幸的是,我沒有2個月的時間來處理這個問題。我很生氣,我已經花了2天! : -/ –

+0

關於frefreshtoken的返回。我已經創建了一個服務器應用程序,該應用程序在配置完成後無需任何用戶交互即可運行但是在幾天前(它已經運行了2個月沒有問題),可以看到服務器上已經打開了多個Auth頁面,請求訪問應用程序以使用Google Drive。即使它要求Auth,它仍然有效。任何線索爲什麼發生這種情況? –

+0

應該可能是一個單獨的問題。我也看到了這一點,並把它放到谷歌隨機過期刷新令牌。在日誌中檢查400無效的授權,看看是否是原因。您的應用有可能從多個地方申請刷新令牌嗎?我相信如果是這樣的話,那些新的刷新令牌可能會過期舊的令牌。 – pinoyyid

1

好吧,我終於解決了上面的第二個問題,我終於得到一個工作的GoogleCredential對象與訪問令牌和刷新令牌。

我一直試圖通過修改MyClass(管理憑證的範圍)中的範圍列表來解決範圍問題。最後,我需要調整我的修改版DriveCommandLine(最初用於獲取授權碼的範圍)中的範圍。我加了2個範圍從Oauth2Scopes:

GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
    httpTransport, jsonFactory, CLIENT_ID, CLIENT_SECRET, 
    Arrays.asList(DriveScopes.DRIVE, Oauth2Scopes.USERINFO_EMAIL, Oauth2Scopes.USERINFO_PROFILE)) 
    .setAccessType("offline").setApprovalPrompt("force").build(); 

增加對用戶信息的範圍,讓我在以後獲取用戶標識MyClass中。我現在可以使用userid將憑證存儲在數據庫中以供重複使用(不必每次都讓用戶轉到URL)。我也按照pinoyyid的建議將訪問類型設置爲「離線」。

3

Oath2Scopes導入如下:

import com.google.api.services.oauth2.Oauth2Scopes; 

您必須的jar文件 '谷歌API服務-的oauth2-V2-rev15-1.8.0-beta.jar' 在你的類路徑訪問該軟件包。它可以下載here

不,我不知道如何獲取憑證,而不必訪問授權URL至少一次並複製代碼。我修改了MyClass來存儲和檢索數據庫中的憑證(在我的情況中,它是一個包含userid,accesstoken和refreshtoken的簡單表)。這樣,我只需要獲取授權碼,一旦獲得訪問/刷新標記,我就可以重新使用它們來創建GoogleCredential對象。下面是如何了Imake的GoogleCredential對象:

GoogleCredential credential = new GoogleCredential.Builder().setJsonFactory(jsonFactory) 
      .setTransport(httpTransport).setClientSecrets(clientid, clientsecret).build(); 
    credential.setAccessToken(accessToken); 
    credential.setRefreshToken(refreshToken); 

只需輸入您的客戶端ID,clientsecret,和的accessToken以上refreshToken。

我真的沒有太多時間來分離和整理我的整個代碼,將它發佈在這裏,但如果您仍然有問題,請告訴我,我會看看我能做些什麼。雖然,你實際上是在向盲人尋求指導。我對這整個系統的理解非常粗略!

乾杯, 布賴恩

相關問題