STRAVA는 전 세계적으로 유명한 자전거 기록 어플입니다. 자전거 이외에 달리기, 사이클, 등산, 테니스 등 많은 운동에 대한 활동량 기록(Activity Record)을 지원합니다. 활동량 기록은 SNS를 통해서 공유 가능하고, 상대 기록과 순위를 볼 수 있습니다. 최근 한국에서도 많은 자전거 매니아 분들이 사용 있으며, 특히 유럽과 미국에서 상당한 수의 사용자를 가지고 있습니다.
STRAVA에서는 운동 기기나 스마트 와치를 직접 연동을 하지는 않지만, 각종 운동 데이터를 연동을 통해서 데이터를 수집하고 있으며, 무료/유료 서비스로 활동량 분석에 대한 분석 데이터를 제공합니다.
STRAVA가 제공하는 서비스는 REST API 형태로 공개하고 있어 STRAVA 서버에서 데이터를 얻어와 자신만의 웹 페이지나 모바일 앱을 개발할 수 있습니다. 이 과정에서 Strava API를 활용해야 하며, 본 포스팅은 STRAVA API 에 대한 연동 방법을 설명하도록 하겠습니다.
Strava API 연동 방법 요약
Strava API는 OAuth 2.0을 사용하여 API 인증(Authentication)을 하고 있습니다. Strava는 OAuth 2.0은 표준을 잘 따르고 있어 Google API (Gmail 예제) 나 다른 API 서버와 연동한 경험이 있다면 쉽게 사용할 수 있습니다.
Strava API를 사용하는 전체적인 과정을 요약하면 아래와 같습니다.
- API 애플리케이션 등록하기
- Strava 인증 서버로 Request Access 요청
- 사용자 데이터 접근에 대한 권한 확인 및 동의 과정
- Strava 인증 서버에서 Authorization code를 내려줌
- Authorization code로 Refresh Token 얻기
- Refresh Token으로 Access Token 얻기
- Access token으로 Strava API 호출
STRAVA API에 연동 방법은 Strava 개발자 사이트의 developers.strava.com/docs/getting-started/ 와 아래 유튜브 튜토리얼 동영상에도 자세히 설명되어 있으니 참고해주세요.
1. API 애플리케이션 등록하기
Strava 계정을 https://www.strava.com/register에서 만들고, API 사용을 위한 애플리케이션을 "내 API 애플리케이션" 사이트에서 등록해야 합니다. 애플리케이션을 등록 신청하면 Strava 서버에서 애플리케이션 승인 과정을 거치게 되고, 승인 완료 시점에서는 클라이언트 ID(client id)와 암호(client secrete)를 할당받습니다. 클라이언트 ID는 12345678과 같이 숫자로 되어 있고, 클라이언트 암호는 abcdefg152 EAG와 같이 스트링으로 할당을 합니다. 참고로, Strava API는 일일 요청/15분 간 API 호출에 대한 사용량에 제한이 있습니다.
애플리케이션 등록하는 과정에서 웹사이트와 OAuth 2.0에서 필요한 승인 콜백 도메인 (=Redirect URL) 지정해야 합니다. 승인 콜백 도메인은 굳이 웹 서버가 설치는 되어 있지 않더라도 상관없으며, 인터넷 상에서 접속 가능한 도메인만을 가지고 있으면 됩니다.
2. Strava 인증 서버로 Request Access 요청
Request Access 과정은 Strava 인증 서버(https://www.strava.com/oauth/mobile/authorize)로 API 인증을 위한 Authorization code을 얻는 과정입니다. 추후 Authorization code를 사용해서 Refresh token과 Access token을 할당받습니다.
curl 명령어로는 다음과 같고, Postman 활용하면 아래와 같이 사용할 수 있습니다. 참고로, Android와 I-OS의 sample code는 developers.strava.com/docs/authentication/을 참고하세요.
curl 명령어
$ curl https://www.strava.com/oauth/mobile/authorize&\
client_id=123456&\
response_type=code&\
approval_prompt=auto&\
scope=read,read_all,activity:read_all,profile:read_all&\
redirect_uri=https://kibua20.example.com
Postman 명령어
Request Parameter에 대한 설명은 아래와 같습니다.
3. 사용자 데이터 접근에 대한 권한 확인 및 동의 과정
Request Access에 대한 응답으로 Strava서버에서는 App에 대한 데이터 접근 권한에 대해서 '사용자 동의'를 받습니다. 테스트 앱으로 만들어본 사용자 동의는 아래와 그림과 같습니다. 사용자 동의 팝업에서는 API 신청 시 사용한 App 이름, 아이콘, API 접근 권한(scope)을 표시합니다. 사용자가 데이터 접근에 대해서 명시적으로 '승인'을 해야 다음 단계로 진행되고, '취소'를 한다면 데이터 접근을 할 수 없습니다.
4. Strava 인증 서버에서 Authorization code를 내려줌
사용자가 데이터 접근 권한을 승인하면 Strava서버에서 API 신청 시 등록한 승인 콜백 도메인(redirect URL)으로 authorization code를 내려줍니다. 아래 예제에서 형광색으로 표시한 부분입니다. 실제 프램그램에서는 Strava서버에서 호출한 Redirect URL을 웹 서버에서 parsing 해서 다음 step으로 진행하도록 구현해야 합니다.
Sample 서버 응답-Authorization code
https://kibua20.example.com/?state=&code=a07369fbac4147951254125b37bc0&scope=read,activity:read_all,profile:read_all,read_all
5. Authorization code로 Refresh Token 얻어오기
앞 단계에서 얻은 Authorization code와 API 등록 시 할당받은 clientid, client_secrete를 parameter로 설정해서 https://www.strava.com/oauth/token로 로 Request POST 요청해야 합니다. Post parameter 중 grant_type을 'authorization_code'로 설정해야 합니다.
Strava서버에서는 이에 대한 응답(response)으로 refresh token과 access token을 내려줍니다. Refresh Token은 유효 기간이 길며, Access token을 얻을 수 있기 때문에 외부로 유출되지 않는 보안 영역에 저장을 해야 합니다. Access Token은 짧은 기간에만 유효한 값으로 일정 시간이 지나면 Access 권한을 유지하지 못합니다.
Refresh Token
POST https://www.strava.com/oauth/token?client_id=[YOUR CLIENT ID]&client_secret=[YOUR CLIENT SECRET]&code=[CODE FROM SERVER]&grant_type=authorization_code
curl명령어
curl -X POST https://www.strava.com/oauth/token \
-d client_id=YOUR_CLIENTID \
-d client_secret=YOUR_CLIENTSECRET \
-d code=YOUR_AUTHORIZATIONCODE \
-d grant_type=authorization_code
Postman 명령어
서버 응답
{
"token_type": "Bearer",
"expires_at": 1606940900,
"expires_in": 21600,
"refresh_token": "b1234567891234567891234567891234567892",
"access_token": "f1123456789123456789123456789123456789A",
"athlete": {
"id": 123456,
"username": null,
"resource_state": 2,
"firstname": "Kibua20",
"lastname": "@gmail.com",
"city": "Jongno-gu",
"state": "Seoul",
"country": "South Korea",
"sex": null,
"premium": false,
"summit": false,
"created_at": "2020-12-02T02:18:53Z",
"updated_at": "2020-12-02T14:20:20Z",
"badge_type_id": 0,
"profile_medium": "https://lh5.googleusercontent.com/-fEkogmj8x5w/AAAAAAAAAAI/AAAAAAAAAAA/AMZuucmd74ppgP7X6rqGZA_IYVtWuC22zQ/s96-c/photo.jpg",
"profile": "https://lh5.googleusercontent.com/-fEkogmj8x5w/AAAAAAAAAAI/AAAAAAAAAAA/AMZuucmd74ppgP7X6rqGZA_IYVtWuC22zQ/s96-c/photo.jpg",
"friend": null,
"follower": null
}
}
6. Refresh Token으로 Access Token 얻기
API 호출 시 Refresh Token을 사용해서 Access Token을 얻어오는 과정입니다. Request parmater에서 grant_type을 'refresh_token'으로 설정해야 합니다.
Refresh Token Exchange
POST https://www.strava.com/oauth/token?client_id=[YOUR CLIENT ID]&client_secret=[YOUR CLIENT SECRET]&grant_type=refresh_token&refresh_token=[TOKEN FROM SERVER]
curl 명령어
curl -X POST https://www.strava.com/oauth/token \
-d client_id=YOUR_CLIENTID \
-d client_secret=YOUR_CLIENTSECRET \
-d refresh_token=TOKEN FROM SERVER \
-d grant_type=refresh_token
Postman 명령어
서버 응답
서버 응답으로 Access Token 값이 할당되어 있고, expire_in과 expire_at 값으로 유효 기간을 알려줍니다. 유효 기간이 지난 상태에서 API를 호출하면 404 에러(Permission denied)를 응답으로 받기 때문에 API 호출 전에 Access token의 유효 기간을 반드시 확인 후 호출해야 합니다. 만일 access token의 유효 기간이 지났으면 Refresh token을 가지고 access token을 다시 얻어야 합니다.
{
"token_type": "Bearer",
"access_token": "abcdef12345678945615265123121",
"expires_at": 1606938622,
"expires_in": 20714,
"refresh_token": "b1234567891234567891234567891234567892"
}
7. Access token으로 Strava API 호출
Strava API reference에서 제공하는 API 를 호출하는 단계입니다. 앞 단계에서 얻은 Access Token을 Request parameter로 설정해야 API 사용 승인이 됩니다.
Strava에서는 다양한 API를 제공하고 있습니다. 예를 들어 Activites를 구하는 API는 아래와 같습니다.
Strava API (Activities list)
$ curl -H Authorization: Bearer [your access_token] \
https://www.strava.com/api/v3/activities?name=activity_by_api&type=Run&start_date_local=2020-12-02T02:18:53Z&elapsed_time=500&description=run by api&distance=100&trainer=1&commute=1
API Response
[
{
"resource_state": 2,
"athlete": {
"id": 73248226,
"resource_state": 1
},
"name": "activity_by_api",
"distance": 100.0,
"moving_time": 500,
"elapsed_time": 500,
"total_elevation_gain": 0,
"type": "Run",
"workout_type": null,
"id": 4420560973,
"external_id": null,
"upload_id": null,
"start_date": "2020-12-01T17:18:53Z",
"start_date_local": "2020-12-02T02:18:53Z",
"timezone": "(GMT+09:00) Asia/Seoul",
"utc_offset": 32400.0,
"start_latlng": null,
"end_latlng": null,
"location_city": null,
"location_state": null,
"location_country": "South Korea",
"start_latitude": null,
"start_longitude": null,
"achievement_count": 0,
"kudos_count": 0,
"comment_count": 0,
"athlete_count": 1,
"photo_count": 0,
"map": {
"id": "a4420560973",
"summary_polyline": null,
"resource_state": 2
},
"trainer": true,
"commute": true,
"manual": true,
"private": true,
"visibility": "only_me",
"flagged": false,
"gear_id": null,
"from_accepted_tag": null,
"average_speed": 0.2,
"max_speed": 0.0,
"has_heartrate": false,
"heartrate_opt_out": false,
"display_hide_heartrate_option": false,
"pr_count": 0,
"total_photo_count": 0,
"has_kudoed": false
}
]
Strava Web에서 확인하면 아래와 같이 activity를 확인할 수 있습니다.
※ 참고 사이트:
Authentication: https://developers.strava.com/docs/authentication
Webhooks: https://developers.strava.com/docs/webhooks
API docs: https://developers.strava.com/docs/reference
Basic info: https://developers.strava.com/docs
관련 글:
[개발환경/Tips] - Spotify 한국에서 사용하는 방법
[모바일 SW 개발/REST API] - 외부 망에서 Localhost를 접속하기: ngrok (일부 무료)
[모바일 SW 개발/REST API] - 외부 망에서 Localhost를 접속하기: localtunnel (무료, domain제공)
[모바일 SW 개발/REST API] - 무료 REST API 테스트 프로그램: Postman (설치, 활용법)
[모바일 SW 개발/REST API] - 공공 데이터 Open API 사용법: 코로나 확진자 현황 API (sample code)
[개발환경/우분투] - Docker 개념과 명령어 사용 방법 및 예제
[개발환경/Oracle Cloud] - 오라클 클라우드 '평생' 무료 VM 만들기 (Google Cloud 무료 조건 비교)
[모바일 SW 개발/Python] - Python: JSON 개념과 json 모듈 사용법
[개발환경/Google Cloud Platform] - Google Cloud Platform을 활용하여 평생 '무료' PC 만들기
[모바일 SW 개발/REST API] - Service Account(JWT)을 활용한 Google Calendar API 사용
[모바일 SW 개발/REST API] - JWT(JSON Web Token) Encoding 방법 (Python sample code)
[모바일 SW 개발/REST API] - Google Gmail API 사용 방법 (2) - Sample code
[모바일 SW 개발/REST API] - Google gmail API 사용 방법 (3) - Sample code
[모바일 SW 개발/Python] - Python JSON 사용 시 TypeError: Object of type bytes is not JSON serializable
댓글