11

DriveCommandLine という Google Drive Quick Start アプリケーションを正常にインストールして実行しました。また、ドライブ アカウント内のファイルの 1 つのファイル情報を取得するように少し調整しました。

私が今やりたいことは、資格情報を何らかの方法で保存し、ユーザーが毎回 Web ページにアクセスして認証コードを取得することなく再利用することです。OAuth 2.0 資格情報を取得して使用する手順が記載されたこのページを確認しました。サンプル クラス (MyClass) を使用するために、Credential オブジェクトがインスタンス化されている DriveCommandLine の行を変更しました。

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)

私はこれらの API (Google ドライブと OAuth) を 2 日間調べてきましたが、ほとんど進歩していません。上記のエラーと、一般的に永続的な資格情報を取得する際の問題について、助けていただければ幸いです。

この全体の構造は、私には不必要に複雑に思えます。Google のユーザー名とパスワードを渡して単純な Credential オブジェクトを作成できない理由を説明したい人はいますか?

ありがとう、ブライアン O キャロル、ダブリン、アイルランド

* アップデート *

OK、上記のエラーを回避したばかりで、新しいエラーが発生しました。

最初の問題を回避する方法は、MyClass.getFlow() を変更することでした。json ファイルから GoogleClientServices オブジェクトを作成する代わりに、クライアント ID とクライアント シークレットを文字列として直接入力できる別のバージョンの GoogleAuthorizationCodeFlow.Builder を使用しました。

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

私が今抱えている問題は、フロー (GoogleAuthorizationCodeFlow オブジェクト) を使用して Credentials オブジェクトの認証コードを交換しようとすると、次のエラーが発生することです。

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

ありがとう!

4

3 に答える 3

13

あなたの痛みが分かります。私は2ヶ月ですが、まだ驚いています。

私の学びのいくつか...

  • ユーザー権限を要求する場合は、「offline=true」を指定してください。これは(「時々」原文のまま)refreshtokenを返します。これは、アクセス許可が制限されたパスワードと同じくらい優れています。これを保存して、いつでも (ユーザーが取り消すまで) 再利用して、アクセス トークンを取得できます。

  • 私の感じでは、Google SDK は助けになるというよりは邪魔になると思います。1 つずつ使用するのをやめ、REST API を直接呼び出すようになりました。

  • 最後のポイントとして、Google clientlogin プロトコルを (単に) 使用して、前世代の API にアクセスできます。ただし、これは完全に非推奨であり、まもなく無効になります。OAuth は、本質的に複雑な承認をきめ細かく制御できるように設計されています。ですから、複雑であることには同意しますが、不必要に複雑だとは思いません。私たちは複雑な世界に住んでいます:-)

あなたと私の経験から、開発コミュニティは、目前のタスクに集中できるように、これらのものをバックミラーに入れるための統合されたドキュメントとレシピをまだ必要としていることを示しています.

于 2012-09-18T15:15:02.550 に答える
3

Oath2Scopes は次のようにインポートされます。

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

そのパッケージにアクセスするには、クラス パスに jar ファイル「google-api-services-oauth2-v2-rev15-1.8.0-beta.jar」が必要です。ここからダウンロードできます。

いいえ、認証 URL に少なくとも 1 回アクセスしてコードをコピーすることなく資格情報を取得する方法がわかりません。データベースから資格情報を保存および取得するようにMyClassを変更しました (私の場合は、ユーザー ID、アクセストークン、およびリフレッシュトークンを含む単純なテーブルです)。この方法では、認証コードを 1 回取得するだけで済み、アクセス/リフレッシュ トークンを取得したら、それらを再利用して GoogleCredential オブジェクトを作成できます。GoogleCredential オブジェクトを作成する方法は次のとおりです。

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

上記の clientid、clientsecret、accessToken、refreshToken を入力するだけです。

ここに投稿するためにコード全体を分離して整理する時間はあまりありませんが、それでも問題が解決しない場合はお知らせください。できることを確認します。とはいえ、あなたは効果的に盲人に道を尋ねています。このシステム全体に対する私の理解は非常に大ざっぱです!

乾杯、ブライアン

于 2012-09-21T08:45:26.930 に答える
1

わかりました。ようやく上記の 2 番目の問題を解決し、アクセス トークンとリフレッシュ トークンを使用して、機能する GoogleCredential オブジェクトを取得しています。

MyClass (資格情報を管理するもの)のスコープのリストを変更することで、スコープの問題を解決しようとし続けました。最後に、変更したバージョンのDriveCommandLine (認証コードを取得するために最初に使用されたもの)のスコープを調整する必要がありました。Oauth2Scopes から 2 つのスコープを追加しました。

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 でユーザー ID を取得できるようになりました。これで、ユーザー ID を使用して資格情報をデータベースに保存し、再利用できるようになりました (毎回ユーザーに URL にアクセスさせる必要はありません)。また、pinoyyid の提案に従って、アクセス タイプを「オフライン」に設定しました。

于 2012-09-19T11:56:11.163 に答える