Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

GoogleAPIのアクセストークンとリフレッシュトークン

はじめに

先日GoogleのAPIを使う際に見落としでNot FoundエラーとBad Requestのエラーがありましたので、メモとしてまとめます。

Googleのコンソールからプロジェクト作成

API認証情報の作成

image.png

1. OAuthクライアントID

利用者は画面から認可同意を行う場合はこちらを選択
image.png

アプリケーション種類、名前、承認済みのリダイレクトURIは3つは入力すると、クライアント ID、クライアント シークレットを生成されました。

2. サービスアカウントキー

画面操作不要で裏でJSON形式でアクセストークンを取得。バッチなどの処理の場合はこちらを選択
image.png

JSON形式でファイルをダウンロードする

※APIのClientのライブラリを利用して通信
https://developers.google.com/api-client-library/java/google-api-java-client/oauth2

認可コードの取得

クライアント、スコップを設定してURLからアクセス

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly&
 access_type=offline&
 include_granted_scopes=true&
 redirect_uri=http%3A%2F%2localhost:8080&
 response_type=code&
 client_id=上記で取得したクライアントID

Google側に同意すると、URLから認可コードを取得できます。
http://localhost:8080/?code=xxxxxxxxxxxx&scope=yyyyyyyyyyy

※1 scopeは下記のURLに確認できます。
https://developers.google.com/identity/protocols/googlescopes
※2 redirect_uriは設定した承認済みのリダイレクトURI
※3 access_typeはonline、offlineを設定可能。offline + 初回目の場合のみToken APIをアクセスするとrefresh_tokenをもらえる。

アクセストークンの取得

仕様

image.png

image.png

ポイント1:POSTメソッド。GETメソッドだとNG
ポイント2:ヘッダーに「Content-Type: application/x-www-form-urlencoded」を設定。設定しないまたはJSONを設定するとNG。

サンプルコード

Test.java
        String url = "https://www.googleapis.com/oauth2/v4/token";

        CloseableHttpClient httpclient = HttpClients.createDefault();

        HttpPost request = new HttpPost(url);
        List<BasicNameValuePair> parameters = new ArrayList<BasicNameValuePair>();
        parameters.add(new BasicNameValuePair("code", authorizationCode)); //上記取得した認可コード
        parameters.add(new BasicNameValuePair("client_id", oAuthClientId)); //コンソールにAPI認証情報のクライアントID
        parameters.add(new BasicNameValuePair("client_secret", oAuthClientSecret)); //コンソールにAPI認証情報のクライアントシークレット
        parameters.add(new BasicNameValuePair("redirect_uri", "http://localhost:8080")); //設定した承認済みのリダイレクトURI
        parameters.add(new BasicNameValuePair("grant_type", "authorization_code")); //固定

        HttpEntity entity = new UrlEncodedFormEntity(parameters);
        request.setEntity(entity);

        request.setHeader("Content-Type", "application/x-www-form-urlencoded");

        CloseableHttpResponse response = httpclient.execute(request);
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            String result = EntityUtils.toString(response.getEntity(), "UTF-8");
            System.out.println(result);
        }
        response.close();

レスポンスのフィールド:
image.png

ここまでアクセストークンが取得できましたので、Googleからデータ取得はできます。
ヘッダーにアクセストークンを設定する例です。
curl -H "Authorization: Bearer <access_token>" https://www.googleapis.com/drive/v2/files

リフレッシュトークンを使ってアクセストークン更新

アクセストークンが期限あります。一定期間(60分)を経過すると、無効になります。このとき、再度認可コードを取得してもよいのですが、
利用者に面倒なので、リフレッシュトークンを使ってアクセストークン再発行するのは一般的です。

仕様

アクセストークンと同じ感じです。
image.png

image.png

サンプルコード

Test.java
        String url = "https://www.googleapis.com/oauth2/v4/token";

        HttpPost request = new HttpPost(url);
        List<BasicNameValuePair> parameters = new ArrayList<BasicNameValuePair>();
        parameters.add(new BasicNameValuePair("refresh_token", "xxxxxxx")); //もっているリフレッシュトークン
        parameters.add(new BasicNameValuePair("client_id", oAuthClientId)); //コンソールにAPI認証情報のクライアントID
        parameters.add(new BasicNameValuePair("client_secret", oAuthClientSecret)); //コンソールにAPI認証情報のクライアントシークレット
        parameters.add(new BasicNameValuePair("redirect_uri", "http://localhost:8080")); //設定した承認済みのリダイレクトURI
        parameters.add(new BasicNameValuePair("grant_type", "refresh_token")); //固定

        HttpEntity entity = new UrlEncodedFormEntity(parameters);
        request.setEntity(entity);

        request.setHeader("Content-Type", "application/x-www-form-urlencoded");

        CloseableHttpClient httpclient = HttpClients.createDefault();
        CloseableHttpResponse response = httpclient.execute(request);
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            String result = EntityUtils.toString(response.getEntity(), "UTF-8");
            System.out.println(result);
        }
        response.close();

レスポンス例です。
image.png

サンプルの通り、リフレッシュトークンがないので、リフレッシュトークンも無効になったら、認可コード取得からやり直すとなります。

参考URL:https://developers.google.com/identity/protocols/OAuth2WebServer

以上

chenglin
システムエンジニア
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away