HttpClient SendAsyn c возврат неавторизованного первого запроса - PullRequest
0 голосов
/ 31 марта 2020

Мой метод входа в систему logi c отправляет запрос в TokenController [AllowAnonymous], чтобы получить токен авторизации, а затем внедрить токен аутентификации в метод GetUser, отправив запрос в UserController [Authorized]. Я попробовал авторизованную конечную точку на Почтальоне, она хорошо работает. Тем не менее, он всегда дает сбой при первом запросе, я изменил код только для проверки того, что, если он вернет Unauthorized, повторно отправит запрос, затем он пройдет. Сомневаюсь, что первый запрос httpClient.SendAsyn c теряет заголовки Authoriaztion. У кого-нибудь есть предложения?

public class LoginController : Controller 
{
    private string GetToken(string username, string password)
    {
        using (var httpClient = new HttpClient())
        {
            var httpRequestMessage = new HttpRequestMessage
            {
                RequestUri = new Uri(_restServiceOptions.GetRestServiceUrl("/tokens")),
                Method = HttpMethod.Post
            };
            httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json; charset=utf-8");
            httpRequestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            var tokenAuthentication = new DTO.TokenAuthentication
            {
                UsernameOrEmailAddress = username.Base64Encode(),
                Password = password.Base64Encode()
            };

            var deserializeObject = JsonConvert.SerializeObject(tokenAuthentication);

            httpRequestMessage.Content = new StringContent(deserializeObject, Encoding.UTF8, "application/json");

            using (var response = httpClient.SendAsync(httpRequestMessage).Result)
            {
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    var apiResponse = JObject.Parse(response.Content.ReadAsStringAsync().Result);
                    var jwToken = apiResponse.GetValue("Data").ToObject<string>();
                    // Problem starts from here, look at the method GetAuthUser below
                    var user = RestHelper.GetAuthUser(RestServiceOptions restServiceOptions, string jsonWebToken);
                    if (user != null)
                    {
                        return user;
                    }
                    else
                    {
                        throw new Exception("User not found");
                    }
                }
            }
        }
    }
}

internal class RestHelper
{
    internal static DTO.User GetAuthUser(RestServiceOptions restServiceOptions, string jsonWebToken)
    {
    using (var httpClient = new HttpClient())
    {
        var httpRequestMessage = new HttpRequestMessage
        {
            RequestUri = new Uri(restServiceOptions.GetRestServiceUrl("/Users/GetJwtUser")),
            Method = HttpMethod.Get
        };
        httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json; charset=utf-8");
        httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + jsonWebToken);
        // Always get unauthorized after the first time request sent by SendAsync
        using (HttpResponseMessage response = httpClient.SendAsync(httpRequestMessage).Result)
        {
            if (response.StatusCode == HttpStatusCode.OK)
            {
                var apiResponse = JObject.Parse(response.Content.ReadAsStringAsync().Result);
                return apiResponse.GetValue("Data").ToObject<DTO.User>();
            }
            if (response.StatusCode == HttpStatusCode.Unauthorized)
            {
                // Resend the request by GetAsync if unauthorized just for testing 
                // This second time request sent, it passes
                var resendRes = httpClient.GetAsync(httpRequestMessage.RequestUri).Result;
                if (resendRes.IsSuccessStatusCode)
                {
                   var resendApiResponse = JObject.Parse(resendRes.Content.ReadAsStringAsync().Result);
                   var user = resendApiResponse.GetValue("Data").ToObject<DTO.User>();
                }

                throw new Exception("Unauthorized");
            }
            if (response.StatusCode == HttpStatusCode.NotFound)
            {
                throw new Exception("NotFound");
            }
            if (response.StatusCode == HttpStatusCode.NotModified)
            {
                return null;
            }
        }
    }
    return null;
}
...