private async Task <HttpResponseMessage> SendInnerAsync(Func <HttpRequestMessage> request) { do { var response = await client.SendAsync(request()); if (response.IsSuccessStatusCode) { return(response); } if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized) { var res = await RefreshTokenAsync(); if (!res) { return(response); } TokenRefreshed = true; } else { ErrorListener?.Invoke(response.ReasonPhrase); return(response); } } while (true); }
/// <summary>clinet.SendAsync の wrapper /// 認証系処理失敗時に、内部で oauth 系の処理を実施する /// refresh_token 失効時の認証処理が確認とれていない /// </summary> /// <param name="request"><see cref="HttpClient"/> では、一度送信した <see cref="HttpRequestMessage"/> の再利用が行えない /// ※async/awaitなどの関係上? <see cref="HttpRequestMessage"/>を生成する Function を引数にとり、 /// 正常に疎通できるまで、 <see cref="HttpRequestMessage"/> を生成する</param> /// <returns>正常系 200 系の場合の <see cref="HttpResponseMessage"/></returns> private async Task <HttpResponseMessage> SendInnerAsync(Func <HttpRequestMessage> request) { do { var response = await client.SendAsync(request()); if (response.IsSuccessStatusCode) { return(response); } // error 発生時に 内容を解析して refresh / 再認証を行う var content = await response.Content.ReadAsStringAsync(); var apierror = content.ConvertToModel <ApiError>(); if (IsAccessTokenExpired(apierror)) { var res = await RefreshTokenAsync(); if (!res) { return(response); } TokenRefreshed = true; } else if (IsRefreshTokenExpired(apierror)) { var res = await AuthorizeAsync(); if (!res) { return(response); } TokenRefreshed = true; } else { ErrorListener?.Invoke(apierror.Message); return(response); } } while (true); }
private async Task <bool> RefreshTokenAsync() { var request = GetRequestMessage(GetUriNoVersion("oauth/token"), mediaType: MediaTypeFormUrlEncoded); var parameters = new Dictionary <string, string> { { "client_id", WebApiSetting.ClientId }, { "redirect_uri", RedirectUri }, { "grant_type", "refresh_token" }, { "refresh_token", WebApiSetting.RefreshToken }, }; request.Content = new StringContent(GetFormUrlEncodedEntity(parameters), Encoding.UTF8, MediaTypeFormUrlEncoded); var response = await client.SendAsync(request); var content = await response.Content.ReadAsStringAsync(); if (!response.IsSuccessStatusCode) { ErrorListener?.Invoke($"トークンのリフレッシュに失敗しました。{Environment.NewLine}{response}{Environment.NewLine}{content}"); return(false); } return(ParseTokenContent(content)); }
/// <summary>連携された 請求ID に対しての 入金ステータス更新</summary> /// <param name="ids">idの配列</param> /// <param name="isMatched">true:2:消込済, false:0:未設定</param> /// <returns>一件でもエラーがあればエラー</returns> public async Task <bool> PatchPaymentAsync(IEnumerable <string> ids, bool isMatched) { var value = new MFModels.UpdateItem(isMatched); var jsonContent = new StringContent(value.ConvertToJson(), Encoding.UTF8, MediaTypeJson); Func <string, HttpRequestMessage> getRequestMessage = (id) => GetRequestMessage(GetUri($"billings/{id}/billing_status/payment"), new HttpMethod("PATCH"), initializer: request => request.Content = jsonContent); var result = true; try { foreach (var id in ids) { var response = await SendInnerAsync(() => getRequestMessage(id)); if (!response.IsSuccessStatusCode) { var content = await response.Content.ReadAsStringAsync(); ErrorListener?.Invoke(content); result = false; break; } if (id != ids.Last()) { await Task.Delay(TimeSpan.FromSeconds(RequestIntervalSecondsForDefaultApi)); } } } catch (Exception ex) { ErrorListener?.Invoke(ex.ToString()); } return(result); }
/// <summary> /// 認証コードより、access_token / refresh_token を取得する処理 /// </summary> /// <param name="authorizationCode"></param> /// <returns></returns> private async Task <bool> GetTokenAsync(string authorizationCode) { var request = GetRequestMessage(GetUri("Auth/Token"), MediaTypeFormUrlEncoded); var parameters = new Dictionary <string, string> { { "grant_type", "authorization_code" }, { "code", authorizationCode }, { "client_id", WebApiSetting.ClientId }, { "client_secret", WebApiSetting.ClientSecret }, { "redirect_uri", RedirectUri } }; request.Content = new StringContent(GetFormUrlEncodedEntity(parameters), Encoding.UTF8, MediaTypeFormUrlEncoded); var response = await client.SendAsync(request); var content = await response.Content.ReadAsStringAsync(); if (!response.IsSuccessStatusCode) { ErrorListener?.Invoke($"トークンの取得に失敗しました。{Environment.NewLine}{response}{Environment.NewLine}{content}"); return(false); } return(ParseTokenContent(content)); }