fitbit API を使いたいので OAuth2 を学ぶ
fitbit と OAuth2
こんにちは、事業開発部の大矢です。
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として想定したフローです。以下にシーケンス概要を示します。 図中の()の数字は、以降の説明の該当箇所を表します。
アプリケーションの登録
まず、fitbitのサイトでアプリケーションを登録します。 とはいえ、今回はアプリケーション自体は作りません。ですが、APIを呼び出すためのClient ID、Client Secretを得るために行います。
以下のように入力し、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が表示されます。これを覚えておきます。
OAuth 2.0 tutorial page
アプリケーションの登録が済んだら、そこで発行された各種情報を使用して、チュートリアル「OAuth 2.0 tutorial page 」を進めます。
以降、このチュートリアルをAuthorization code grantのフローにそって説明していきます。
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の認証画面が表示され、認証が成功すると、認可画面が表示されます。
これはフローの(1)の部分にあたります。
許可すると(フローの(2))、ブラウザはredirect_uriで指定したところへリダイレクトしようとします。ですがこのURLは存在しないので、エラーになります。(フローの(3))
リダイレクトには失敗しますが、code(authorization code)はアドレスバーに表示されているので、この値を覚えておきます。
Webアプリケーションを用意した場合は、ブラウザからサーバーへリダイレクトで、このauthorization codeが渡される、といった動作を想定します。
1A Get Code
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))。
すると以下のようなレスポンスが得られます。(フローの(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
上記で得られたJSONを2: Parse responseのテキストエリアに入力すると、パースしてくれて、3 Make RequestのOAuth 2.0 Access Tokenの部分にaccess tokenが表示されます。
3 Make Request
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について理解を深めることができました。一石二鳥でした。
ではまた。