Strava has recently announced changes to the Strava OAuth flow. On October 15, 2019 all applications using the old flow will stop working.
In short, long lived tokens are no longer supported and you must obtain a refresh token that gives you a short-lived access token. As long as you are holding a valid access token you may be getting a newer refresh token, too.
On the plus side, short lived tokens are good for security, since a leaked access token expires quickly. Refresh tokens are good for security because they never have to leave your app. Finally, tokens get more granular permission scopes, reducing data exposure. The downside is additional burden on the developer and additional security risk for non-interactive applications (see below).
Migrating my Strava Slack Bot
My Strava Slack Bot is a classic OAuth application in which users connect their account to Strava in Slack. The migration involved the following.
- Before we stored a user’s
token_type, now we store a
- Before we made Strava API calls using
acess_token, now we have to check the token expiration time and potentially refresh
- Refreshing the token involves a
refresh_tokenand storing the updated
access_tokenwith a new
token_expires_atas well as a potentially changed
refresh_token. An old
access_tokencan be used here during the migration period instead of a
Works as intended. See slack-strava@96b934 for complete implementation details.
Migrating my Github Pages Site
My run.dblock.org website has a Travis-CI job that fetches runs from Strava as described in this blog post. Migrating this task was a little bit more complicated.
The app settings page no longer carries a long lived access token. The old one will expire in October 2019.
The first step is to obtain an OAuth token with
activity:read_all scope. Because mine is not an interactive app I used strava-oauth-token that makes the API calls and navigates to a web page using a browser.
Instead of setting
STRAVA_API_TOKEN we now need
STRAVA_CLIENT_SECRET in the Travis-CI configuration as well as
STRAVA_API_REFRESH_TOKEN from above to obtain the actual access token each time the website cron runs. However, the result may yield a new refresh token that will need to be rotated, so entering the refresh token in the Travis-CI UI is not going to work.
We can encrypt and store the token in
The script that refreshes the token will encrypt a new value if necessary in run.dblock.org@2af902. And we already have code that commits changes to Github.
If Someone at Strava is Reading
The migration for OAuth apps makes total sense. The migration for an application that doesn’t require interaction is both annoying and less secure for two reasons.
- The application now needs to store a client ID and secret at runtime in order to obtain a refreshed access token. Before it only stored a single long lived access token.
- The developer is forced to store the refresh token in potentially less secure ways and is now required to store an updated refresh token at “runtime” after obtaining an access token.
I think the Strava developer UI should just let you create a long lived personal access token with any given scope that can be revoked from the same UI, which is what Github API allows for non-interactive apps. Storing that token would be more secure than having to store a client ID and secret.