/// <summary> /// Attempts to refresh the access token. /// </summary> /// <param name="response">The <see cref="FitbitResponse"/>.</param> /// <returns>If successful, true. Otherwise, false.</returns> private bool TryRefreshAccessToken(out FitbitResponse response) { var refreshToken = string.Empty; if (this.user != null) { refreshToken = this.user.TryGetClaimValue(FitbitClient.RefreshTokenClaimType); } using (var client = new HttpClient()) { client.BaseAddress = new Uri(this.apiBaseAddress); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue( "Basic", Encoding.UTF8.EncodeBase64( string.Format("{0}:{1}", this.clientId, this.clientSecret) ) ); // Build the request. var request = new HttpRequestMessage(HttpMethod.Post, "/oauth2/token"); { var parameters = new List <KeyValuePair <String, String> >(); { parameters.Add( new KeyValuePair <String, String>("grant_type", "refresh_token") ); parameters.Add( new KeyValuePair <String, String>("refresh_token", refreshToken) ); } request.Content = new FormUrlEncodedContent(parameters); } var result = client.SendAsync(request).Result; response = new FitbitResponse(result.StatusCode, result.Content.ReadAsStringAsync().Result); if (response.StatusCode == HttpStatusCode.OK) { if (response.Response != null) { var schema = JSchema.Parse(Resources.RefreshAccessTokenSchema); if (response.Response.IsValid(schema)) { dynamic data = response.Response; this.user.AddOrUpdateClaim( FitbitClient.AccessTokenClaimType, (string)data.access_token ); this.user.AddOrUpdateClaim( FitbitClient.RefreshTokenClaimType, (string)data.refresh_token ); return(true); } } } return(false); } }
/// <summary> /// Makes a request to the Fitbit API. /// </summary> /// <param name="request">An <see cref="IFitbitRequest"/>.</param> /// <returns>An <see cref="FitbitResponse"/>.</returns> /// <exception cref="InvalidOperationException">Thrown when the <see cref="IFitbitRequest"/> /// does not contain the required properties.</exception> private FitbitResponse MakeRequest(IFitbitRequest request) { var accessToken = string.Empty; if (this.user != null) { accessToken = this.user.TryGetClaimValue(FitbitClient.AccessTokenClaimType); } using (var client = new HttpClient()) { client.BaseAddress = new Uri(this.apiBaseAddress); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); foreach (var header in request.GetHeaders()) { client.DefaultRequestHeaders.TryAddWithoutValidation(header.Name, header.Value); } HttpResponseMessage result; if (request.Action == FitbitRequestAction.Get) { result = client.GetAsync(request.GetUri()).Result; } else if (request.Action == FitbitRequestAction.Post) { result = client.PostAsync(request.GetUri(), null).Result; } else if (request.Action == FitbitRequestAction.Delete) { result = client.DeleteAsync(request.GetUri()).Result; } else { throw new ArgumentOutOfRangeException("request.Action"); } var response = new FitbitResponse(result.StatusCode, result.Content.ReadAsStringAsync().Result); // The access token probably needs refreshing. If this is // the first attempt then try the refresh token. if (result.StatusCode == HttpStatusCode.Unauthorized) { if (!request.SupressTokenRefresh) { // Only try to get a refresh token once... request.SupressTokenRefresh = true; if (this.TryRefreshAccessToken(out response)) { return(this.MakeRequest(request)); } } } return(response); } }