Facebook Graph APIを使用してユーザー情報を取得する

最近、FacebookログインとFacebook Graph APIを使用した機能を実装しました。
本記事では、Facebook Graph APIを用いてユーザー情報を取得する方法と注意点について紹介します。
これからFacebook Graph APIを使用する方の参考になれば幸いです。

# 注意
この情報は2017年11月2日現在のものです。
Graph APIのバージョンはv2.10です。

# Graph APIとは

Graph APIの公式サイトには、Graph APIについて下記のように説明されています。
[Graph API](https://developers.facebook.com/docs/graph-api?locale=ja_JP)<br>

>グラフAPIは、Facebookのソーシャルグラフにデータを取り込んだり、データを取り出したりするための主な方法です。データのクエリ、新しい記事の投稿、写真のアップロード、アプリで行う必要があるその他のさまざまなタスクに利用できるローレベルのHTTPベースのAPIです。

Graph APIを用いることで、ユーザーの情報を取得・投稿することができます。


# 通信の流れ
Graph APIとの通信の流れはざっくりと以下のようになります。


![fb通信.png](https://qiita-image-store.s3.amazonaws.com/0/63241/75d45c88-d45a-51e3-59f2-f6ad8e0f76f1.png "fb通信.png")

1. ユーザーがFacebookにログイン、ユーザーデータへのアクセス許可を行う
2. FacebookがAccess Tokenを発行する
3. Access Tokenをサーバーサイドに渡す
4. Access Tokenの不正チェックを行う
5. ユーザーの情報を取得する


今回はサーバサイド側に注目し、4,5について説明します。

# Access Tokenの不正チェックを行う

1〜3の過程でFacebookから発行されたAccess Tokenを用いて、Facebookとの接続を行います。<br>
その際、トークンハイジャックを防ぐためにクライアントから送られたAccess Tokenが、自分のFacebookアプリケーションに対して発行されたAccess Tokenかどうかをチェックする必要があります。<br>
Access Tokenが不正なものではないかどうかをチェックする際には、`/debug_token`エンドポイントを使用します。

### エンドポイント
```
/debug_token?input_token={ユーザーのAccess Token}&access_token={app_id}|{app_secret}
```


`/debug_token`エンドポイントのリクエストパラメーターにはinput_tokenとaccess_tokenが必要です。
**ユーザーのAccess Tokenが正しいことをチェックする際には、ユーザーのAccess Tokenは、acccess_tokenではなくinput_tokenを記述する**という点に注意してください。

access_tokenには、Facebookアプリケーションの情報を記述します。
具体的には、`｛Facebookアプリケーションのapp_id}|{Facebookアプリケーションのapp_secret}`を記述します。


例えば、
ユーザーのAccess Tokenがuser、Facebookのapp_idが123、app_secretがsecretとした場合、下記のようなリクエストになります。

```
/debug_token?input_token=user&access_token=123|secret
```


### レスポンス
正しいinput_token, access_tokenを入力した場合は、下記のようなレスポンスが返ります。

```JSON
{
  "data": {
    "app_id": app_id,
    "type": "APP",
    "application": アプリケーション名,
    "is_valid": true,
    "scopes": [
    ]
  }
}
```

不正なAccess Tokenを入力した場合は下記のようなレスポンスが返ります。

```JSON
{
  "error": {
    "message": "Invalid OAuth access token.",
    "type": "OAuthException",
    "code": 190,
    "fbtrace_id": ""
  }
}
```

また、違うアプリケーションのAccess Tokenを入力した場合は下記のようなレスポンスが返ります。

```JSON
{
  "error": {
    "message": "(#100) The App_id in the input_token did not match the Viewing App",
    "type": "OAuthException",
    "code": 100,
    "fbtrace_id": ""
  }
}
```

エラーの種類が複数あることに注意してください。
エラーが発生していない場合、Access Tokenが有効なものであると判断できます。


参考： [アクセストークン：デバッグとエラー処理](https://developers.facebook.com/docs/facebook-login/access-tokens/debugging-and-error-handling?locale=ja_JP)

Access Tokenの確認後、ユーザーの情報を取得します。

# ユーザー情報の取得
## ユーザーの基本情報（名前・年齢など）
ユーザーの基本情報を取得したい場合、`/{user_id}`というエンドポイントを使用します。
また、自分の情報に限り`/me`というエンドポイントで情報を取得できます。
今回は`/me`を使用します。

`/me`エンドポイントのパラメーターに、取得したいフィールドを記述します。
例えば、ユーザーのID、名前、プロフィール画像を取得したい場合は`/me?fields=id,name,picture`と記述します。
実際に`/me?fields=id,name,picture`エンドポイントを叩いた際は、下記のレスポンスが返ってきます。

### エンドポイント
```
/me?fields=id,name,picture
```

### レスポンス
```JSON
{
  "id": ユーザーID,
  "name": 名前,
  "picture": {
    "data": {
      "is_silhouette": 初期ユーザー画像かどうか(プロフィール画像を設定してない場合trueになる),
      "url": 画像のURL
    }
  }
}
```

filedsに指定できるフィールドは他にも多くあります。

参考：[Graph API Reference User](https://developers.facebook.com/docs/graph-api/reference/user)


## 友人・友人数を取得したい場合
ユーザーの友人数や、同じアプリを使用している友人を取得したい場合は、`/me`のfilelsにfriendsを指定します。
このエンドポイントを叩く際には**このエンドポイントで取得できる友人は、ユーザーのすべての友人ではなく同じFacebookアプリケーションを使用している友人のみが取得できる**という点に注意してください。

### エンドポイント
```
/me?fields=friends
```

### レスポンス
```JSON
{
  "data": [
    {
      "name": 友人の名前,
      "id": ユーザーID
    },
    ...
  ],
  "summary": {
    "total_count": ユーザーの友人数
  }
}
```

`summary`の中の`total_count`がユーザーの総友人数です。
また友人一覧は、`data`に配列として返ってきます。
data内の配列には、友人それぞれの名前とユーザーIDが記載されています。


## プロフィール画像のサイズを指定したい場合
プロフィール画像を取得したい場合はfieldsにpictureを指定して`/me?fields=picture`となります。
プロフィール画像など、取得する画像のサイズを変更したい場合は、`width`,`hight`というパラメータをつけることによって画像のサイズを指定することができます。

### エンドポイント
```
/me?fields=picture.width(720).hight(720)
```

### レスポンス
```JSON
{
  "picture": {
    "data": {
      "height": 720,
      "is_silhouette": false,
      "url": 指定したサイズの画像のURL,
      "width": 720
    }
  },
  "id": ユーザーID
}
```

## アクセス許可の確認したい場合
初回認証時にユーザー情報への読み取りが許可されている場合でも、ユーザー自身が[アプリ設定画面](https://www.facebook.com/settings?tab=applications)から自由に、アプリのアクセス許可を変更することができます。
ユーザーが下記のようにチェックを外し、アクセス許可を変更することで、今まで取得できていたデータが取得できなくなります。

![scope.png](https://qiita-image-store.s3.amazonaws.com/0/63241/294ff7f9-f3bd-949d-2956-58360c7eb73e.png "scope.png")

そのため、ユーザー情報の取得する前にAccess Tokenのアクセス許可を確認する必要があります。
アクセス許可を確認する場合は`/me`エンドポイントのfieldsにpermissionsを指定します。

### エンドポイント
```
/me?fields=permissions
```

### レスポンス

```JSON
{
  "permissions": {
    "data": [
      {
        "permission": "public_profile",
        "status": "granted"
      },
      {
        "permission": "publish_actions",
        "status": "declined"
      },
      {
        "permission": "email",
        "status": "declined"
      },
    ]
  },
  "id": ユーザーID
}

```

アプリに付与されているアクセス許可それぞれの名前とステータスが返ってきます。
statusについての説明は下記の様になります。

| status | 説明 |
|--------|--------|
| granted | アクセス許可されている|
| declined |アクセス許可されていない|

statusが`declined`のアクセス許可があった場合は、ユーザーに再度アクセス許可を求める必要があります。

参考： [User permissions](https://developers.facebook.com/docs/graph-api/reference/user/permissions/)

# Tips
## テストアプリケーション
Facebookアプリケーションをリリースまで公開したくない場合、開発環境用のアプリケーションを作成することができます。
[アプリ一覧画面](https://developers.facebook.com/apps/)から、アプリを選択し『Create Test App』ボタンから開発環境用のテストアプリケーションをつくることができます。

![test_application.png](https://qiita-image-store.s3.amazonaws.com/0/63241/fa46a1fb-025d-7dbb-1927-6aaf8ffce206.png "test_application.png")



## Graph API Explorer
APIのリクエストパラメーターやレスポンスを試したいときは、[Graph API Explorer](https://developers.facebook.com/tools/explorer/)が便利です。<br>


![Graph_API_Explorer.png](https://qiita-image-store.s3.amazonaws.com/0/63241/fc21a5b2-e837-f5d6-5ef9-12e57eae458d.png "Graph_API_Explorer.png")

### 1. アプリケーションを選択
まず確認を行いたいアプリケーションを選択します。
APIのレスポンスを確認したいだけのときはGraph API Explorerのままで良いと思います。

### 2. アクセス許可を行いAccess Tokenを取得
『Get Token』→『Get User Access Token』で、取得したい情報のアクセス許可をチェックしAccess Tokenを取得します。

### 3. エンドポイントとパラメーターを記述し実行
確認したいエンドポイントとパラメータを記述し『Submit』ボタンを押すとレスポンスの確認ができます。


## Access Tokenのアクセス許可を確認したいとき

Access Tokenのアクセス許可を確認したい場合には、[Access Token Debugger](https://developers.facebook.com/tools/debug/accesstoken/)が便利です。
Access Tokenを入力すると、下記のようにユーザー名、許可しているアクセス許可一覧（Scopes）などが確認できます。

![Access_Token_Debugger.png](https://qiita-image-store.s3.amazonaws.com/0/63241/70b172a2-0bee-fe8b-0bbf-119c367ece30.png "Access_Token_Debugger.png")



# まとめ
本記事では、Facebook Graph APIの利用方法と注意点について紹介しました。<br>
Access Tokenの不正チェックの際はAccess Tokenをinput_tokenに記述すること、友人は同じアプリケーションを使用している友人しか取得できないという点は特に注意してください。


# 参考資料
[Graph API ドキュメント](https://developers.facebook.com/docs/graph-api?locale=ja_JP)<br>
[Facebookログインについて](https://developers.facebook.com/docs/facebook-login?locale=ja_JP)


Icon made by Freepik from [http://www.flaticon.com/](http://www.flaticon.com/)