public async Task <OAuth2AccessToken> RefreshTokenAsync(FitbitClient client) { string postUrl = FitbitOauthPostUrl; var content = new FormUrlEncodedContent(new[] { new KeyValuePair <string, string>("grant_type", "refresh_token"), new KeyValuePair <string, string>("refresh_token", client.AccessToken.RefreshToken), }); HttpClient httpClient; if (client.HttpClient == null) { httpClient = new HttpClient(); } else { httpClient = client.HttpClient; } var clientIdConcatSecret = OAuth2Helper.Base64Encode(client.AppCredentials.ClientId + ":" + client.AppCredentials.ClientSecret); httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", clientIdConcatSecret); HttpResponseMessage response = await httpClient.PostAsync(postUrl, content); string responseString = await response.Content.ReadAsStringAsync(); return(OAuth2Helper.ParseAccessTokenResponse(responseString)); }
public FitbitHttpMessageHandler(FitbitClient fitbitClient, IFitbitInterceptor interceptor) { this.FitbitClient = fitbitClient; this.interceptor = interceptor; responseHandler = ResponseHandler; //Define the inner must handler. Otherwise exception is thrown. InnerHandler = new HttpClientHandler(); }
/// <summary> /// Creates the processing request pipeline using the message handlers /// </summary> /// <param name="authorization"></param> /// <param name="interceptors"></param> /// <returns></returns> internal static HttpMessageHandler CreatePipeline(this FitbitClient client, List<IFitbitInterceptor> interceptors) { if(interceptors.Count > 0) { // inspired by the code referenced from the web api source; this creates the russian doll effect FitbitHttpMessageHandler innerHandler = new FitbitHttpMessageHandler(client, interceptors[0]); var innerHandlers = interceptors.GetRange(1, interceptors.Count - 1); foreach (var handler in innerHandlers) { var messageHandler = new FitbitHttpMessageHandler(client, handler); messageHandler.InnerHandler = innerHandler; innerHandler = messageHandler; } return innerHandler; } return null; }
/// <summary> /// HttpClient and hence FitbitClient are designed to be long-lived for the duration of the session. This method ensures only one client is created for the duration of the session. /// More info at: http://stackoverflow.com/questions/22560971/what-is-the-overhead-of-creating-a-new-httpclient-per-call-in-a-webapi-client /// </summary> /// <returns></returns> public FitbitClient GetFitbitClient(OAuth2AccessToken accessToken = null) { if (Session["FitbitClient"] == null) { if (accessToken != null) { var appCredentials = (FitbitAppCredentials)Session["AppCredentials"]; FitbitClient client = new FitbitClient(appCredentials, accessToken); Session["FitbitClient"] = client; return(client); } else { throw new Exception("First time requesting a FitbitClient from the session you must pass the AccessToken."); } } else { return((FitbitClient)Session["FitbitClient"]); } }
//Final step. Take this authorization information and use it in the app public async Task <ActionResult> Callback() { FitbitAppCredentials appCredentials = (FitbitAppCredentials)Session["AppCredentials"]; var authenticator = new OAuth2Helper(appCredentials, Request.Url.GetLeftPart(UriPartial.Authority) + "/Fitbit/Callback"); string code = Request.Params["code"]; OAuth2AccessToken accessToken = await authenticator.ExchangeAuthCodeForAccessTokenAsync(code); /*Console.WriteLine("Zilu-debug"); * Console.Write(accessToken); * Console.WriteLine(accessToken);*/ //Store credentials in FitbitClient. The client in its default implementation manages the Refresh process FitbitClient fitbitClient = GetFitbitClient(accessToken); //20171025 Pandita: removed saving tokens //SyncFitbitCred(accessToken); //return RedirectToAction("Index", "Home"); return(RedirectToAction("Sync", "UserDatas")); // redirect to UserdatasController.cs/Sync(). }
public async Task <HttpResponseMessage> InterceptResponse(Task <HttpResponseMessage> response, CancellationToken cancellationToken, FitbitClient Client) { if (response.Result.StatusCode == System.Net.HttpStatusCode.Unauthorized)//Unauthorized, then there is a chance token is stale { var responseBody = await response.Result.Content.ReadAsStringAsync(); if (IsTokenStale(responseBody)) { Debug.WriteLine("Stale token detected. Invoking registered tokenManager.RefreskToken to refresh it"); await Client.RefreshOAuth2TokenAsync(); //Only retry the first time. if (!response.Result.RequestMessage.Headers.Contains(CUSTOM_HEADER)) { var clonedRequest = await response.Result.RequestMessage.CloneAsync(); clonedRequest.Headers.Add(CUSTOM_HEADER, CUSTOM_HEADER); return(await Client.HttpClient.SendAsync(clonedRequest, cancellationToken)); } else if (response.Result.RequestMessage.Headers.Contains(CUSTOM_HEADER)) { throw new FitbitTokenException(response.Result, message: $"In interceptor {nameof(OAuth2AutoRefreshInterceptor)} inside method {nameof(InterceptResponse)} we received an unexpected stale token response - during the retry for a call whose token we just refreshed {response.Result.StatusCode}"); } } } //let the pipeline continue return(null); }
public Task <HttpResponseMessage> InterceptRequest(HttpRequestMessage request, CancellationToken cancellationToken, FitbitClient Client) { return(null); }