Node.jsのOAuthを使ってGoogleDriveAPIを叩いてみた


## はじめに
最近何かとFacebookのタイムライン等でGoogleI/O 2015が話題になっており、今後InboxのようにGooglePlatformから関連サービスを生み出す開発の方が増えてくるのではないかと思ったので、今回はNode.jsをつかって、簡単にGoogleDriveAPIを叩くアプリケーションを作ってみようとおもいます。
### 参照源
今回はこちらのドキュメントに従って開発をしています。

* [google-api-nodejs-client](https://github.com/google/google-api-nodejs-client)
* [Quickstart: Run a Drive App in Node.js](https://developers.google.com/drive/web/quickstart/quickstart-nodejs)

##STEP1.Google Developers Consoleでプロジェクトの作成

###「APIと認証」から、GoogleDriveAPIを有効化
* [google developers console](https://console.developers.google.com/)にアクセス
* ログインしたらプロジェクトの作成を選択します。

![Screen Shot 0027-05-30 at 5.28.04 PM.png](https://qiita-image-store.s3.amazonaws.com/0/6702/b17ab248-94ee-c0c1-c80a-1ea7d8e529b1.png "Screen Shot 0027-05-30 at 5.28.04 PM.png")

* 作成したプロジェクトを選択し、APIの認証をおこないます
* 左カラムのAPIを選択

![Screen Shot 0027-05-30 at 5.19.06 PM.png](https://qiita-image-store.s3.amazonaws.com/0/6702/eb32fd1c-1629-40e3-66aa-398cec8d7aea.png "Screen Shot 0027-05-30 at 5.19.06 PM.png")

* google Drive API を選択し、「APIを有効にする」を選択
![Screen Shot 0027-05-30 at 4.51.20 PM.png](https://qiita-image-store.s3.amazonaws.com/0/6702/1afaa90d-7614-1a12-e14f-eabce681f071.png "Screen Shot 0027-05-30 at 4.51.20 PM.png")

###クライアントIDの作成
有効にしたAPIのクライアントIDを作成します。
* 認証情報を選択
![Screen Shot 0027-05-30 at 4.52.29 PM.png](https://qiita-image-store.s3.amazonaws.com/0/6702/b7e5d6ad-304c-10b7-fc75-aa02ba4a1d76.png "Screen Shot 0027-05-30 at 4.52.29 PM.png")
* 「インストールされているアプリケーション」を選択して作成
* アプリ名を任意のタイトルで入力して同意画面を作成してください
![Screen Shot 0027-05-30 at 4.52.39 PM.png](https://qiita-image-store.s3.amazonaws.com/0/6702/b5895dfe-bffb-72e9-6df4-b16f4a29c158.png "Screen Shot 0027-05-30 at 4.52.39 PM.png")

* 同意画面の設定が完了したら、クライアントIDの作成を行います。
* 「インストールされているアプリケーション」の「その他」を選択し、クライアントIDを生成
![Screen Shot 0027-05-30 at 4.53.29 PM.png](https://qiita-image-store.s3.amazonaws.com/0/6702/d85a1a48-292f-fe5a-9d16-accdf85781ec.png "Screen Shot 0027-05-30 at 4.53.29 PM.png")

* プロジェクトのTOPページで以下の項目が作成されていばOK
	* クライアントID
	* クライアントシークレット
	* リダイレクトURL

![Screen Shot 0027-05-30 at 5.25.24 PM.png](https://qiita-image-store.s3.amazonaws.com/0/6702/2cc4becc-2ae3-b0a4-883a-4e7afd5d4828.png "Screen Shot 0027-05-30 at 5.25.24 PM.png")

##STEP2.Node.jsでアプリケーションを作成
次に、Node.jsでAPIを叩くアプリケーションを作成していきます。
基本的なNode.jsのインストールやnpmに関してはこちらを参照すると良いかと思います。
[いまさら聞けないNode.jsの基礎知識とnpm、Gulpのインストール (1/2)](http://www.atmarkit.co.jp/ait/articles/1501/09/news040.html)
###npmでgoogleAPIをインストール
プロジェクトディレクトリを作成したらnpmで以下のコマンドを実行

```
% npm install googleapis --save                                                                                                              

npm WARN deprecated jws@0.0.2: Security update: Versions below 3.0.0 are deprecated.
npm WARN deprecated tap-consumer@0.0.1: This module is not supported. Please use 'tap' instead.
npm WARN installMany tap-consumer was bundled with tap@0.3.3, but bundled package wasn't found in unpacked tree
npm WARN deprecated tap-results@0.0.2: This module is not supported. Please use 'tap' instead.
googleapis@2.0.4 node_modules/googleapis
├── string-template@0.2.1
├── async@0.9.2
├── request@2.54.0 (caseless@0.9.0, aws-sign2@0.5.0, forever-agent@0.6.1, form-data@0.2.0, stringstream@0.0.4, oauth-sign@0.6.0, tunnel-agent@0.4.0, isstream@0.1.2, json-stringify-safe@5.0.1, node-uuid@1.4.3, qs@2.4.2, combined-stream@0.0.7, mime-types@2.0.12, http-signature@0.10.1, bl@0.9.4, tough-cookie@1.2.0, hawk@2.3.1, har-validator@1.7.1)
├── gapitoken@0.1.4 (jws@0.0.2)
└── google-auth-library@0.9.6 (lodash.noop@3.0.0, jws@3.0.0, request@2.51.0, gtoken@1.1.1)

% ls node_modules/googleapis

CONTRIBUTING.md COPYING         MIGRATING.md    README.md       apis            jsdoc-conf.json lib             node_modules    package.json    scripts         templates

```
node_module以下にgoogleapisが保存されていることを確認して下さい。

###qucikstart.jsの作成
* 公式リファレンスに従い、プロジェクトディレクトリ直下に以下のファイルを作成
* ここで、STEP1で作成したクライアントID、クライアントシークレット、リダイレクトURLを入力してください。

```quickstart.js
var readline = require('readline');
var google = require('googleapis');
var OAuth2 = google.auth.OAuth2;

var CLIENT_ID = 'YOUR CLIENT ID HERE',
    CLIENT_SECRET = 'YOUR CLIENT SECRET HERE',
    REDIRECT_URL = 'YOUR REDIRECT URL HERE',
    SCOPE = 'https://www.googleapis.com/auth/drive.file';

var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

var auth = new OAuth2(CLIENT_ID, CLIENT_SECRET, REDIRECT_URL);

var url = auth.generateAuthUrl({ scope: SCOPE });
var getAccessToken = function(code) {
  auth.getToken(code, function(err, tokens) {
    if (err) {
      console.log('Error while trying to retrieve access token', err);
      return;
    }
    auth.credentials = tokens;
    upload();
  });
};
var upload = function() {
  var drive = google.drive({ version: 'v2', auth: auth });
  drive.files.insert({
    resource: {
      title: 'My Document',
      mimeType: 'text/plain'
    },
    media: {
      mimeType: 'text/plain',
      body: 'Hello World!'
    }
}, console.log);
};
console.log('Visit the url: ', url);
rl.question('Enter the code here:', getAccessToken);

```

## STEP3.実際にAPIを叩く
### 認証コードの発行
* nodeで作成したquickstart.jsを実行します

```
% node quickstart.js
Visit the url:  https://accounts.google.com/o/oauth2/auth?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.file&response_type=code&client_id=275817081938-98r3p3mmik51sfaism7od7pjp0r2g02j.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob
Enter the code here:

```
* 発行されたURLにアクセスし、認証コードを取得
* Webブラウザでアクセスをすると、STEP1.で設定した「同意画面」が表示されます
![Screen Shot 0027-05-30 at 5.10.49 PM.png](https://qiita-image-store.s3.amazonaws.com/0/6702/c0818319-2a8e-6cf6-11ce-c0416bbc3b35.png "Screen Shot 0027-05-30 at 5.10.49 PM.png")

* 同意すると、「認証コード」が発行されるので、コピーしましょう

![Screen Shot 0027-05-30 at 5.10.54 PM.png](https://qiita-image-store.s3.amazonaws.com/0/6702/7137ed29-bd67-8f78-ca7e-37b6af788e8a.png "Screen Shot 0027-05-30 at 5.10.54 PM.png")

### アクセストークンの発行とAPIへのアクセス
* コマンドラインに戻り、取得した認証コードをペーストしてエンター

```
% node quickstart.js
Visit the url:  https://accounts.google.com/o/oauth2/auth?scope=...
Enter the code here:
null { kind: 'drive#file',
  id: '0B5vaUuhAA1KpaW1tZVNVOU5jYXM',
  etag: '"AmpO9uzbs3m4f4SIcYKV4LhQRzY/MTQzMjk3NjU2NjkwNA"',
  selfLink: 'https://www.googleapis.com/drive/v2/files/0B5vaUuhAA1KpaW1tZVNVOU5jYXM',
  webContentLink: 'https://docs.google.com/uc?id=0B5vaUuhAA1KpaW1tZVNVOU5jYXM&export=download',
  alternateLink: 'https://docs.google.com/file/d/0B5vaUuhAA1KpaW1tZVNVOU5jYXM/edit?usp=drivesdk',
  iconLink: 'https://ssl.gstatic.com/docs/doclist/images/icon_10_text_list.png',
  title: 'My Document',
  mimeType: 'text/plain',
  labels:
   { starred: false,
     hidden: false,
     trashed: false,
     restricted: false,
     viewed: true },
  createdDate: '2015-05-30T09:02:47.087Z',
  modifiedDate: '2015-05-30T09:02:46.904Z',
  modifiedByMeDate: '2015-05-30T09:02:46.904Z',
  lastViewedByMeDate: '2015-05-30T09:02:46.904Z',
  markedViewedByMeDate: '1970-01-01T00:00:00.000Z',
  version: '526254',

```

### 生成されたファイルを確認
* GoogleDriveにアクセスしてみましょう。
* 「My Document」というファイルが作成されていて「Hello World」が表示されていれば、成功です。

![Screen Shot 0027-05-30 at 5.15.28 PM.png](https://qiita-image-store.s3.amazonaws.com/0/6702/c7484f64-5787-3c40-0c79-b8827ae95ab4.png "Screen Shot 0027-05-30 at 5.15.28 PM.png")


## 終わりに
### 今回作成したレポジトリ
今回やってみたものを公開しています。

* [gdrive_api](https://github.com/maximum80/gdrive_api)
	* 該当のgoogleのプロジェクトは既に削除したため、IDやSECLET情報はご利用出来ません（.gitignoreし忘れてました）
	* 公式にそって編集しているだけなシンプルなものです
	* 今後もっと様々な機能を実装してみたい

### OAuth周りのプラクティス
1. 認証コードのリクエスト
2. アクセストークンのリクエスト
3. APIの活用

という今回のようなOAuthを活用したAPIの問い合わせの流れというのは様々なAPIでも同様のフローだと思います。
以下の[OAuth2.0に関するGoogleの公式](https://developers.google.com/identity/protocols/OAuth2)等にも丁寧に記載がありますが、これらを参照しOAuthの流れを理解し様々なAPIを活用できるようにしていけると良いかもしれないです。