web-dev-qa-db-ja.com

OAuth2を使用してプログラムでGoogleに対して認証する

Googleに対してプログラムで認証するにはどうすればよいですか? ClientLogin( https://developers.google.com/accounts/docs/AuthForInstalledApps )が廃止されたため、OAuth2を使用してGoogleに対してプログラムによる認証を実行するにはどうすればよいですか?

ClientLoginを使用すると、メールとパスワードのパラメーターを指定して https://www.google.com/accounts/ClientLogin に投稿し、認証トークンを取得できます。

OAuth2では解決策が見つかりません!

私のアプリはJavaバックグラウンドプロセスです。developers.google.com/ accounts/docs/OAuth2InstalledApp#refreshというリンクに従って、更新されたトークンを使用して新しいアクセストークンを取得する方法を見ました。

問題は、新しい有効なアクセストークンがあるときにクエリを実行するためのAnalyticsオブジェクトのインスタンス化方法(たとえば)についてJavaの例が見つからないことです。

これは、「execute()」を呼び出すときに401無効な資格情報を返すコードです。

public class Test {

static final String client_id = "MY_CLIENT_ID";
static final String client_secret = "MY_SECRET";
static final String appName = "MY_APP";

private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
private static final JsonFactory JSON_FACTORY = new JacksonFactory();

static String access_token = "xxxx";
static String refreshToken = "yyyyy";

public static void main (String args[]){

    try {

        GoogleCredential credential = 
            new GoogleCredential.Builder()
                .setTransport(HTTP_TRANSPORT)
                .setJsonFactory(JSON_FACTORY)
                .setClientSecrets(client_id, client_secret).build();
        credential.setAccessToken(access_token);
        credential.setRefreshToken(refreshToken);
        //GoogleCredential
        Analytics analytics = Analytics.builder(HTTP_TRANSPORT, JSON_FACTORY)
            .setApplicationName(appName)
            .setHttpRequestInitializer(credential)
            .build();

        Accounts accounts = analytics.management().accounts().list().execute();
    } catch (Exception e) {
        e.printStackTrace();
    } 
}

何が問題ですか?

26
Andrea Zonzin

インストール済みアプリケーションのOAuth 2フローを確認してください:

https://developers.google.com/accounts/docs/OAuth2InstalledApp

ユーザーは最初にブラウザーで認証する必要がありますが、更新トークンを保存し、それを後続の要求に使用できます。

代替ソリューションについては、デバイスフローまたはサービスアカウントを確認してください。それらは同じドキュメントセットで説明されています。

16

Google Javaクライアントは非常に複雑で文書化が不十分であることがわかりました。ここに、プレーンでシンプルなサーブレット Google Oauth2があります。バックグラウンドプロセスについては、リクエストが必要ですaccess_type = offline。他の人が述べたように、ユーザーに1回限りの認証を行う必要があります。

15
Andrew

OPが元々 OAuth2InstalledApp アプローチをターゲットとしていたことは理解していますが、 OAuth2WebServer アプローチを使用した実用的なソリューションを指摘したいと思います。それらに大きな違いはなく、これは私にとってはうまくいきました。 GoogleのOAuthライブラリは、ほとんどのOAuthダンスを処理し、アクセストークンを簡単に更新できるため、非常に優れていることがわかりました。以下のソリューションは、事前に取得された更新トークンを使用することに依存しています。

受け入れられた回答が示すように、OAuth認証が機能するようにするには(Javaバックグラウンドプロセスであっても)、リクエストはユーザーデータへのアクセスに依存します

ユーザーが最初にブラウザで認証する必要がありますが、その後、更新トークンを保存し、それを後続のリクエストに使用できます。

OPによる以前のコメントから、私は以下を見る

そのため、WebサーバーアプリケーションではOAuth2を使用しました(ここではオフラインアクセスについて説明しています)が、まだ問題があります。
1)ブラウザを介して最初のリクエストを実行し、オフラインアクセス用の自動コードを取得します
2)認証コードのJavaポストを実行し、アクセストークンとリフレッシュトークンを取得します

私が使用したアプローチは次のようなものです

1)ブラウザ経由で最初のリクエストを実行し、オフラインアクセス用の更新トークンを取得します
2)Javaでライブラリに更新トークンを提供すると、ライブラリはアクセストークンなどを取得します

具体的には、 google-api-Java-client library を使用するコードは非常に簡単で、他の場所でcredential.refreshToken();を呼び出しているため、OPのようにアクセストークンを設定していないことに注意してください。 (有効なアクセストークンが既にあるかどうかを確認し、API呼び出しの前に更新を呼び出さない場合)

  private Credential generateCredentialWithUserApprovedToken() throws IOException,
      GeneralSecurityException {
    JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
    HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
    InputStreamReader inputStreamReader =
        new InputStreamReader(jsonFileResourceForClient.getInputStream());
    GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(jsonFactory, inputStreamReader);
    return new GoogleCredential.Builder().setTransport(httpTransport).setJsonFactory(jsonFactory)
        .setClientSecrets(clientSecrets).build().setRefreshToken(REFRESH_TOKEN);
  }

これは私のアプローチのステップ2をカバーしており、ステップ1で述べたREFRESH_TOKENは以下で説明するように取得できることに注意してください。

まず、 ウェブアプリ の事前設定があります。 Googleコンソールで資格情報用のOAuth 2.0クライアントIDを作成しますGoogleClientSecretsオブジェクトに読み込まれるダウンロードされたjsonファイルになります。

つまり.

enter image description here

Google Playgroundコールバックuriを承認済みリダイレクトURIに追加してください

enter image description here

次に、クライアントIDとプレイグラウンド用のクライアントシークレットを用意し、Javaコードにプルできるjsonをダウンロードすることもできます。

enter image description here

REFRESH_TOKENは、次の構成で google oauth playground にリクエストを送信することにより取得されます。ステップ1の前にスコープを選択する前に、設定に移動して、自分の資格情報を提供していることを確認し、そのすぐ下にクライアントIDとシークレットを追加する必要があることに注意してください。

enter image description here

アクセスタイプは this に対応するオフラインです。

リフレッシュトークンの取得については、 https://www.youtube.com/watch?v=hfWe1gPCnzc

これで十分ですし、一度セットアップするだけです!

更新トークンについては、ドキュメント here で説明されているように、ライフサイクルに注意する必要があります

Oauthplaygroundでこれが表示されます

enter image description here

しかし、ドキュメントのポイント4では here

enter image description here

うーん。

また、 を参照してください。ユーザーの介入なしにアプリ(Webまたはインストール済み)を認証するにはどうすればよいですか? (正準?)

10
Matt C

自分自身に代わって認証するアプリケーション(つまり、従来は共有パスワードを使用して役割アカウントにサインインすることで別のアプリケーションに認証するアプリケーション)の場合、Googleが提供するClientLoginに代わるOAuth2はサービスアカウントです:

https://developers.google.com/accounts/docs/OAuth2ServiceAccount

0
breno