こんにちは、サイオステクノロジーの佐藤 陽です。
今回はStravaAPI記事 第二弾ということで、OAuthを利用した認証を試してみます。
公式ドキュメントにも手順は丁寧に書いてあるので、これに従えば割と簡単に実現自体はできると思うのですが
今回はOAuthフローを理解する意味も込め、OAuthの仕様に触れながら解説していきたいと思います。
StravaのAPIも使えるようになって、OAuthの知識も付くので一石二鳥!
好きこそものの上手なれ、ですね。
はじめに
今回、Strava APIで使われている認可のグラントタイプは認可コードグラントです。
他のグラントタイプに関する説明は今回避けますが、認可コードグラントは一番複雑な(丁寧な?)タイプになりますね。
この認可コードグラントのフローと、Stravaのドキュメントで記載されているステップを照らし合わせながら解説していきたいと思います。
また、OAuthの理解にそんなに自信が無い…、なんとなくしか…、という方はこちらの書籍がオススメです!
ネットで色々と記事を読むのもいいですが、これ1冊で体系的に分かりやすく学べるのでおすすめです。
私もこの本から多く学んだので、本記事にも類似した表現があるかとは思いますが、悪しからず。
またStravaのドキュメントにもOAuthに特化したドキュメントがあるので
細かいパラメータの内容などは、こちらもご覧いただくとより理解しやすいかと思います。
認可コードグラント
今回の目的は「アクセストークン」をStravaから取得することです。
アクセストークンさえ取得できてしまえば、前回のブログのようにAPIを実行することができますね。
認可コードグラントでアクセストークンを取得するためには、以下の2つのステップが必要になります。
- 認可コード取得
- アクセストークンの取得
認可コードはいわばアクセストークンの引換券です。
そのため、まずは認可コードを取得し、その認可コードを用いてアクセストークンの取得を行います。
認可コード取得
まず認可コードの取得を試みたいと思います。
Stravaのドキュメントと照らし合わした場合、
D.How to AuthenticateのStep.1 ~ Step.9のフローにあたります。
- Go to https://www.strava.com/settings/api and copy your Client ID
- Paste your Client ID into this URL: http://www.strava.com/oauth/authorize?client_id=[REPLACE_WITH_YOUR_CLIENT_ID]&response_type=code&redirect_uri=http://localhost/exchange_token&approval_prompt=force&scope=read
- Go to a browser
- Paste the URL you edited into the browser window (step 1 and 2 from the graph)
- Hit enter
- When you see the authorization page, click “Authorize” (step 3a from the graph)
- After you click “Authorize,” you should see something like, “this site can’t be reached”
- Stay on that page and look at the URL
- The URL will show the authorization code and scope accepted by the athlete (step 5 from the graph)
リクエストURLの用意
(1)~(2)
前回作成したMy APIアプリケーションからClientIDを取得し、(2)に書かれたURLを組み立てます。
このURLの中身に関しても少し解説したいと思います。
http://www.strava.com/oauth/authorize |
認可エンドポイント |
client_id |
My APIアプリケーション画面から取得できるClientID |
response_type |
値をcodeに設定することで、認可コードのみを要求します。 |
redirect_uri |
認可コードが返される先です。 |
approval_prompt | force(毎回認証) or Auto(一度認証を行えばしばらくはスキップ) |
scope |
APIの処理スコープを設定します。読み取り権限のみなのか、書き込み権限も含めるのか等。 |
認可コードリクエスト
(3)~(5)
ブラウザにURLを貼り付けて実行します。
http://www.strava.com/oauth/authorize?client_id=[REPLACE_WITH_YOUR_CLIENT_ID]&response_type=code&redirect_uri=http://localhost&approval_prompt=force&scope=read
権限確認画面
(6)~(7)
実行すると、Stravaのログイン画面が表示された後、以下のような画面が表示されます。
これがStravaの認可サーバーからユーザーに対して
「SIOS Applicationってアプリがあなたのユーザー情報にアクセスしようとしてるけどいい?」
という確認を取ってるフローになります。
(※”SIOS Application”は前回My APIアプリケーションで設定したアプリケーション名です。)
今回scopeをreadとしているため、「公開プロフィールに関するデータを表示する」という文字が表示されており
もし、scopeにwriteなどを追加した場合は、「変更しようとしているけどいい?」といった文字列も追加されます。
今回は問題ないため、「許可する」ボタンを押して次へ進みます。
すると「ページに到達できません」と表示されます。
ドキュメントにも“this site can’t be reached”と表示される、と書いてあるので今回はこれでOKです。
認可コード取得
(8)~(9)
先ほど、許可を承認した後に「画面が表示されません」といったページが表示されましたが、
重要なのは、この画面で表示されているURLです。
http://localhost/?state=&code=101c09df0d2ab7018fcdb800151a3b05575cc90a&scope=read
クエリパラメータに含まれているcodeの値が、今回目的としていた認可コードです。
これで、第一目標である認可コードが取得できました。
なお、この認可コードの有効期限は一般的に短いものとされているので
もし期限切れになった場合は再度取得の方を行ってください。
ただこの時、
「なんでhttps://www.strava~~~にアクセスしたのに、勝手にhttp://localhost~~~に書き変わってるの?」と思う方もいるかと思います。
これは、ブラウザのリダイレクト機能の働きによってアクセス先のURLが変更となっています。
(5)のステップで、URLにアクセスした後、Stravaの認可サーバーは302番のレスポンスを返します。
HTTP/1.1 302 Found Location: http://localhost/?state=&code=101c09df0d2ab7018fcdb800151a3b05575cc90a&scope=read
おそらくこんな感じです。
この302番のレスポンスは”リダイレクト”のレスポンス番号です。
そのため、ブラウザは302番のレスポンスを受け取った際、LocationのURLにリダイレクトするという挙動を行うのです。
それで今回localhostにリダイレクトされたものの、何も実装していないため「ページに到達できません」と表示されるということです。
本来のアプリの挙動であれば、リダイレクト先でcodeの情報を取得して…という流れになるかと思いますが
今回はブラウザ上で実行しているため、手動でコピペしていく形になります。
アプリ上での動作はこの次の記事でご紹介予定です!
また、余談ですが、今回のURLの中に”state”というパラメータも存在しています。
今回は利用されていませんが、気になった方はこちらのブログで紹介されているのでぜひご覧ください
アクセストークン取得
公式ドキュメントによると、ステップはあと2つです。
10. Copy the authorization code
11. Make a cURL request to exchange the authorization code and scope for a refresh token, access token, and access token expiration date (step 7a from the graph). Replace the client_secret and code. The response should include the refresh token, access token, and access token expiration date (step 8 from the graph).
アクセストークンリクエスト
(10)~(11)
(9)で取得したコードを仕様して、アクセストークン+αの取得を試みます。
ExampleのcURL Requestのコードが記載されていたので
curl -X POST https://www.strava.com/api/v3/oauth/token \ -d client_id=ReplaceWithClientID \ -d client_secret=ReplaceWithClientSecret \ -d code=ReplaceWithCode \ -d grant_type=authorization_code
これをPostmanのインポート機能を使って読み込みます。
読み込んだ後、それぞれの値を設定します。
clientid |
Strava上に構築したアプリのIDです。 |
client_secret |
Strava上に構築したアプリのパスワードのような値です。 |
code | (9)で取得した認可コード |
grant_type |
どのgrant_typeを利用するかを表明します。 |
これを実行すると、レスポンスとして、トークン情報が取得できます。
{
"token_type": "Bearer",
"expires_at": 1676367247,
"expires_in": 21311,
"refresh_token": "3a22208b026dd069a58ffb0b52352c6373dbecfd",
"access_token": "a075c723310df6740040d7b672e0af2bbd35dd3f",
"athlete": {
"id": 13141....,
....
} }
今回、取得を目的としていたaccess tokenも取得できました。
リソース取得
最後に、このアクセストークンを使って、実際にAPIの方を実行してみます。
curl --location --request GET 'https://www.strava.com/api/v3/athlete' \ --header 'Authorization: Bearer a075c723310df6740040d7b672e0af2bbd35dd3'
↓
正しく情報が取得できました!
まとめ
今回は、アクセストークンの取得をOAuthのお作法に倣って行いました。
前回は既に与えられたアクセストークンをコピペするだけでしたが、今回は動的に取得が行えました!
次のブログでは更に一歩進んで、実際にStravaAPIを組み込んだアプリを構築したいと思います。
お楽しみに!