Google DriveのAPIをNode.jsで触る ~ @google-cloud/local-authのサンプル版


既存のメモ通りにうまく動かず試行錯誤しました。

## 認証方式が若干変わった模様......?

以前書いた[Google DriveのAPIをNode.jsから触るメモ](https://qiita.com/n0bisuke/items/4af8f17fb4fe3b9b4831)では、公式の[Node.js quickstart ](https://developers.google.com/drive/api/quickstart/nodejs)に掲載されているコードをもとに実行していましたが、`credentials.json`の作成までは同様で、`token.js`生成のタイミングでリダイレクトエラーが発生するようになりました。

> このサイトにアクセスできませんlocalhost で接続が拒否されました。
> ![スクリーンショット 2022-04-03 3.55.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/982f68aa-9ddc-ebe6-a18d-56d9c6f8dddd.png "スクリーンショット 2022-04-03 3.55.09.png")

クライアントモジュール(googleapis)のバージョンを上げたら認証がうまく通らなくなったのか、生成されるcredentials.jsonの値が変わってしまったのかはイマイチ分かってません。（ちゃんと調べてない）

## @google-cloud/local-authを使った認証サンプル

こちらの認証サンプルは`@google-cloud/local-auth`というモジュールを使ってる模様です。

> https://github.com/googleapis/google-api-nodejs-client/blob/8faa9ff985225d626a3951ff78e723891ec94e71/samples/drive/list.js

ライブラリ準備をします。

```bash
$ npm i @google-cloud/local-auth googleapis@100
```

執筆時点だとちょうどバージョンが100でした。
このライブラリはバージョンが頻繁に上がるので執筆時点の100を指定しています。

```js
'use strict';

const path = require('path');
const {google} = require('googleapis');
const {authenticate} = require('@google-cloud/local-auth');

const drive = google.drive('v3');

async function runSample(query) {
  // Obtain user credentials to use for the request
  const auth = await authenticate({
    keyfilePath: path.join(__dirname, 'credentials.json'),
    scopes: 'https://www.googleapis.com/auth/drive.metadata.readonly',
  });
  google.options({auth});

  const params = {pageSize: 3};
  params.q = query;
  const res = await drive.files.list(params);
  console.log(res.data);
  return res.data;
}

if (module === require.main) {
  runSample().catch(console.error);
}
module.exports = runSample;
```

### 最初の実行でredirect_urisの書き換え指示

プログラムを実行すると、`credentials.json`のredirect_urisの中身を変えろと指示を出されます。

> Error: The provided keyfile does not define a valid
redirect URI. There must be at least one redirect URI defined, and this sample
assumes it redirects to 'http://localhost:3000/oauth2callback'.  Please edit
your keyfile, and add a 'redirect_uris' section.  For example:

```bash
$ node app.js
Error: The provided keyfile does not define a valid
redirect URI. There must be at least one redirect URI defined, and this sample
assumes it redirects to 'http://localhost:3000/oauth2callback'.  Please edit
your keyfile, and add a 'redirect_uris' section.  For example:

"redirect_uris": [
  "http://localhost:3000/oauth2callback"
]
```

最初は`http://localhost`と記載されていますが、
指示通りに`http://localhost:3000/oauth2callback`に変更してみました。

> ![](https://i.gyazo.com/238a127a795c24e98c0d9f39b1348b28.png)

実行すると認証ページがブラウザで開かれます。

> ![](https://i.gyazo.com/4861030704004e542ef561e1ad8cf476.png)

許可して進めると認証成功したっぽい表示が。

> ![スクリーンショット 2022-04-03 4.54.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/296d3026-9fb6-9136-527f-bbf42130e360.png "スクリーンショット 2022-04-03 4.54.53.png")

認証が完了して、コンソールに無事にファイル一覧が表示されました。

```bash
$ node app.js
{
  kind: 'drive#fileList',
  nextPageToken: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  incompleteSearch: false,
  files: [
    {
      kind: 'drive#file',
      id: '1QBZPkNxxxxxxxxxxxxxxxxxxxx'

省略   
```

## まとめ

イマイチ良く分かってないけどこのやり方でAPIアクセスはできました。
リダイレクトが手間なので公式サンプル風にtoken.jsみたいなファイルにストアするのが良いんでしょうね。