fitbit API を使いたいので OAuth2 を学ぶ

fitbit-logo

fitbit と OAuth2

fitbit-homepage

こんにちは、事業開発部の大矢です。

fitbitという活動量計、ご存知でしょうか。 私はfitbitを日々使っていまして、1日の歩数や睡眠時間などを確認しています。

fitbitにはAPIがあり、その認可方式としてOAuth2を採用しています。 ドキュメントを見たところ、APIを叩くためには、それなりにOAuth2を理解していることが求められている気がします。(敷居が高い。。。)

今回は、fitbit APIのチュートリアル「OAuth 2.0 tutorial page」の手順を追いながら、OAuth2、特にAuthorization code grantのフローについて学んでいきたいと思います。

といったことをやってみようと思ったきっかけは、先日のDevIO 2017にて弊社都元のすばらしい講演でOAuth2を学んだことです。さっそく活かしていきます。

Authorization code grant

OAuth2では4つのフローが想定されていますが、 fitbitではImplicit grantとAuthorization code grantを選択できます。 今回はAuthorization code grantを使用します。

Authorization code grant は WebアプリケーションのサーバーサイドをClientとして想定したフローです。以下にシーケンス概要を示します。 図中の()の数字は、以降の説明の該当箇所を表します。

authcodegrant

アプリケーションの登録

まず、fitbitのサイトでアプリケーションを登録します。 とはいえ、今回はアプリケーション自体は作りません。ですが、APIを呼び出すためのClient ID、Client Secretを得るために行います。

fitbit-register

以下のように入力し、Registerボタンを押下します。

  • Application Name
    • 適当に
  • Description
    • 適当に
  • Application Website
    • 適当に
  • Organization
    • 適当に
  • Organization Website
    • 適当に
  • OAuth 2.0 Application token
    • Personalを選択
  • Callback URL
    • 適当に
  • Default Access Type
    • Read-Only

すると、次の画面にClient ID、Client Secretが表示されます。これを覚えておきます。

fitbit-registered

OAuth 2.0 tutorial page

アプリケーションの登録が済んだら、そこで発行された各種情報を使用して、チュートリアル「OAuth 2.0 tutorial page 」を進めます。

以降、このチュートリアルをAuthorization code grantのフローにそって説明していきます。

1: Authorize

各入力欄に以下のように入力します。

fitbit-1-authorize

  • Flow type
    • Authorization Code Flow を選択
  • OAuth 2.0 Client ID
    • アプリケーション登録時に発行されたもの
  • Client Secret
    • アプリケーション登録時に発行されたもの
  • Select Scopes
    • アクセスしたい機能をONにする。とりあえず全部でよいと思う。

すると、以下のようなURLが自動生成されます。

https://www.fitbit.com/oauth2/authorize
?response_type=code
&client_id=XXXXXX
&redirect_uri=http%3A%2F%2F127.0.0.1%3A8080%2F
&scope=activity%20heartrate%20location%20nutrition%20profile%20settings%20sleep%20social%20weight
&expires_in=604800
  • https://www.fitbit.com/oauth2/authorize
    • 認可のエンドポイント
  • response_type
    • Authorization code grantでは"code"を指定する。
  • client_id
    • OAuth 2.0 Client ID
  • redirect_uri
    • Webアプリケーションがリダイレクトを受け取るURL。今回はダミー。
  • scope
    • fitbitでは対象とするデータの種類になっている。
  • expires_in
    • 有効期限

このURLをブラウザで実行すると、fitbitの認証画面が表示され、認証が成功すると、認可画面が表示されます。

fitbit-authz2

これはフローの(1)の部分にあたります。

authcodegrant 2

許可すると(フローの(2))、ブラウザはredirect_uriで指定したところへリダイレクトしようとします。ですがこのURLは存在しないので、エラーになります。(フローの(3))

fitbit-code

リダイレクトには失敗しますが、code(authorization code)はアドレスバーに表示されているので、この値を覚えておきます。

Webアプリケーションを用意した場合は、ブラウザからサーバーへリダイレクトで、このauthorization codeが渡される、といった動作を想定します。

1A Get Code

fitbit-1A-getcode

Codeの入力ボックスに、さきほど入手したauthorization codeを入力します。 入力する際の注意点として、末尾の#_=_は除去します。

すると、access token取得のcurlコマンドが表示されます。

curl -X POST -i
-H 'Authorization: Basic MjI4R0J...'
-H 'Content-Type: application/x-www-form-urlencoded'
-d "clientId=XXXXXX"
-d "grant_type=authorization_code"
-d "redirect_uri=http%3A%2F%2F127.0.0.1%3A8080%2F"
-d "code=6036ca..."
https://api.fitbit.com/oauth2/token
  • Authorization: Basic
    • client_idとsecretをbase64エンコードしたもの。
  • grant_type
    • Authorization code grantでは"authorization_code"を指定する。
  • redirect_uri
    • Webアプリケーションがリダイレクトを受け取るURL。今回はダミー。
  • code
    • 先ほど入手したauthorization code
  • https://api.fitbit.com/oauth2/token
    • access token取得のエンドポイント

このaccess token取得のcurlコマンドを実行します(フローの(4))。

authcodegrant 3

すると以下のようなレスポンスが得られます。(フローの(5))

$ curl -X POST -i 
-H 'Authorization: Basic MjI4R0J...' 
-H 'Content-Type: application/x-www-form-urlencoded' 
-d "clientId=XXXXXX" 
-d "grant_type=authorization_code" 
-d "redirect_uri=http%3A%2F%2F127.0.0.1%3A8080%2F" 
-d "code=6036ca..." 
https://api.fitbit.com/oauth2/token

HTTP/1.1 200 OK
Date: Fri, 07 Jul 2017 05:47:51 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Origin,Accept-Encoding
Cache-control: no-cache, private
Content-Language: ja-JP
X-Frame-Options: SAMEORIGIN
Server: cloudflare-nginx
CF-RAY: 37a882ee7e512e03-NRT

{
  "access_token":"eyJhbGciOi...",
  "expires_in": 28800,
  "refresh_token": "1b25d2190...",
  "scope": "social settings weight profile sleep activity location heartrate nutrition",
  "token_type": "Bearer",
  "user_id": "ZZZZZZ"
}

2: Parse response

fitbit-2-parse-res

上記で得られたJSONを2: Parse responseのテキストエリアに入力すると、パースしてくれて、3 Make RequestのOAuth 2.0 Access Tokenの部分にaccess tokenが表示されます。

3 Make Request

fitbit-3-make-req

OAuth 2.0 Access Tokenの部分は、上で設定された値をそのまま使用します。
API endpoint URLの部分に、使用したいAPIを入力します。 すると、APIを呼び出すcurlコマンドが表示されます。

ここではactivitiesのAPIで、2017年1月の毎日の歩数を取得するようにしてみました。
なおAPIの仕様はswaggerで提供されています。

これを実行すると、APIを呼び出すことができました。(フローの(6))
どうやら1月3日はずっと寝ていたようです。。。

$ curl -i -H "Authorization: Bearer eyJhbGciOi..." https://api.fitbit.com/1/user/-/activities/steps/date/2017-01-01/2017-01-31.json

HTTP/1.1 200 OK
Date: Fri, 07 Jul 2017 05:59:35 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Origin,Accept-Encoding
Cache-control: no-cache, private
Content-Language: en
Fitbit-Rate-Limit-Limit: 150
Fitbit-Rate-Limit-Remaining: 150
Fitbit-Rate-Limit-Reset: 25
X-Frame-Options: SAMEORIGIN
Server: cloudflare-nginx
CF-RAY: 37a894190d896ee1-NRT

{
  "activities-steps": [
    {
      "dateTime": "2017-01-01",
      "value": "6343"
    },
    {
      "dateTime": "2017-01-02",
      "value": "6656"
    },
    {
      "dateTime": "2017-01-03",
      "value": "938"
    },
    ...

チュートリアルは以上となります。(Refresh Tokenについては割愛)

まとめ

fitbit APIのチュートリアル「OAuth 2.0 tutorial page」をこなすことで、fitbit APIを呼び出せるようになり、また同時にOAuth2について理解を深めることができました。一石二鳥でした。

ではまた。