Building a Token Refresh service for the Fitbit API with Azure Functions and C#
We can generate a refresh and access token required to call the Fitbit API programmatically with a simple Timer trigger function.
As part of my personal development, I’m building my own personal health platform in Azure. I like to keep track of a variety of different health metrics, such as daily activity, food intake and sleep patterns. To collect this data, I use a Fitbit Ionic.
In the past, I used to download a monthly CSV file and just do some basic analysis on it. This was a bit tedious as I’d have to do some manual scrubbing of the data before I could do anything with it. This took time that I didn’t really want to waste, so I wanted to create a pipeline that just calls the Fitbit API to retrieve my data without having to manually clean the file myself.
Using the Fitbit API is relatively straight forward. The challenging part can be ensuring that our refresh tokens and access tokens don’t expire on us. By default, these will expire after 8 hours.
Thankfully, we can use a Azure Function Timer Trigger to request new access tokens and Azure Key Vault to store these tokens securely. This article will show you how you can refresh your Access Tokens for the Fitbit API using Azure Functions and Key Vault.
While this example focuses on the Fitbit API, you could apply this method to other API keys.
How refresh tokens and access tokens work for the Fitbit API
Fitbit uses OAuth 2.0 to authorize users and authenticate to the Fitbit API. The OAuth 2.0 framework needs our apps that call the Fitbit API to obtain an Access Token. This is used for making HTTPS requests to the API.
Fitbit supports both Authorization Code Grant and Implicit Grant flows. For my project, I’m using the Authorization Code Grant flow. This is the recommended option for server-to-server communication using an application’s client secret.
Using the Authorization Code Grant Flow, a user will consent to share their Fitbit data with an application with some or all of the scopes. When this consent is given, Fitbit will give us an authorization code as part of a callback URL. Our app will exchange this code for an access and refresh tokens (the ones that we will store in Key Vault).
By default, these tokens will expire. The refresh token is used to obtain access to a new access and refresh token. Refresh tokens can only be used once, so we need to store the new access token and refresh token pair in Key Vault when these are regenerated.
If you want to learn how to set up a application in Fitbit, obtain a client id and client secret and generate the authorization code to be able to generate refresh and access tokens, I highly recommend watching the below video (Shoutout to Franchyze923 for this video! Super helpful!)
Introducing our Function
Once you’ve watched that video, you should have a client id, client secret and a base64 encoded string of your client id and secret concatenated with the colon (Don’t know what I’m on about? Watch the video again 😉)
We’ll need to store this in our Key Vault along with our Refresh Token that we generated earlier.
Before we dive into the code, let’s take a look at what this Function is trying to do end-to-end. Check the following diagram:
Every 6 hours, we want to start a process of refreshing our tokens. We could increase the frequency we refresh our tokens, but 6 hours is fine for my purpose. When we start the function, we want to make a call to the Fitbit API to refresh our tokens.
To do this, I will need my existing refresh token as well as my Fitbit Credentials, which I have stored as secrets in Key Vault. Once we have these, we need to make a request to the Fitbit API using our tokens and credentials to generate new tokens.
Once we have our tokens, we want to save them in Key Vault so the next time we invoke our function to refresh our tokens again, we will use the updated values.
Let’s dive into the code to make this clearer.
Using HTTP Client to make our call
To make calls to the Fitbit API, we can use the HttpClient library! In order to request a new refresh token, we need to make the following API call:
Authorization: Basic Y2xpZW50X2lkOmNsaWVudCBzZWNyZXQ=
We can use the HttpClient library to build our POST request like so:
In this class, we’re doing the following:
- Retrieving our existing Refresh Token and Fitbit Credentials from Key Vault. (I simplified these calls using a wrapper for the Key Vault C# SDK).
- Clearing our request headers, defining the URI we want to make the POST request to and then defining query parameters as part of that URI. We need to use our Refresh Token here.
- Define the request as a POST request to our URI.
- Setting the Content to an empty string, setting the headers and content type to use ‘application/x-www-form-urlencoded’ and setting our AuthorizationHeaderValue to use Basic authentication and passing in our Fitbit Credentials.
- We then make our POST Request, ensure that it is successful and deserialize our response into a RefreshTokenResponse object before returning it.
That RefreshTokenResponse is a custom class I created so that I can use it as a return type. It’s defined as follows:
This class should help deserialize the following sample response into a strong type:
Now that we have our new access token and refresh token, we can save them to Key Vault.
Saving our secrets in Key Vault
To save our refresh and access tokens, we can simply do the following:
Here I’m passing through our RefreshTokenResponse object I got earlier in my RefreshTokenService class and then saving the RefreshToken and AccessToken into Key Vault using the same wrapper from earlier.
Complete function end to end
I’ve broken out these two components into their own classes. It could with some tidying up, but hopefully the example is easy to follow. We can now inject these services into our Function like so:
Generating a new refresh token manually would be a pain. Thankfully with Azure Function timer triggers, we can generate tokens on a schedule. By storing the access token in Key Vault, we can retrieve the token when we need to make calls to the Fitbit API.
While this example focuses on the Fitbit API, hopefully you can apply this example to other services that require you to refresh your access token when needed.
If you want to see the code repository for this sample, you can check it out here:
Contribute to willvelida/MyHealth.Auth.RefreshToken development by creating an account on GitHub.
Hopefully you’ve enjoyed this article. If you have any questions or comments, please feel free to comment below or reach out to me on Twitter.