API вызова HttpClient не проходит проверку подлинности cookie

Попытка вызова API из контроллера с использованием HttpClient и API не распознает пользователя как аутентифицированного и вошедшего в систему. При вызове API из JS у меня нет проблем. Я заметил, что HttpClient отправлял только через HTTP 1.1, и поэтому я обновил до 2.0 настройки DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER флаг, но это не имеет значения. Я перепробовал все комбинации свойств HttpClientHandler, включая UseCookies, и запрос никогда не проверялся.

        using (var handler = new HttpClientHandler {UseDefaultCredentials = true})
        {
            using (var httpClient = new HttpClient(handler))
            {
                var response = httpClient.GetStringAsync(new Uri($"https://localhost:64366/api/")).Result;
            }
        }

В будущем перейду к аутентификации на основе токенов, но сейчас хотелось бы понять, почему существует разница между вызовом API из C# против JS. Это все HTTPS на локальном хосте, использующем ядро ​​asp net 2.2.

1 ответ

Решение

Разница между JS и C# заключается в том, что браузеры автоматически прикрепляют файлы cookie к запросам, и вы должны прикреплять файлы cookie вручную в C#, как упоминалось в разделе juunas.

Для получения и использования файла cookie для аутентификации вы можете использовать следующий шаблон

CookieContainer cookies = new CookieContainer(); //this container saves cookies from responses and send them in requests
var handler = new HttpClientHandler
{
    CookieContainer = cookies
};

var client = new HttpClient(handler);

string authUrl = ""; //your auth url
string anyUrl = ""; //any url that requires you to be authenticated

var authContent = new FormUrlEncodedContent(
    new List<KeyValuePair<string, string>> {
        new KeyValuePair<string, string>("login", "log_in"),
        new KeyValuePair<string, string>("password", "pass_word")
        }
    );

//cookies will be set on this request
HttpResponseMessage auth = await client.PostAsync(authUrl, authContent);
auth.EnsureSuccessStatusCode(); //retrieving result is not required but you will know if something goes wrong on authentication

//and here retrieved cookies will be used
string result = await client.GetStringAsync(anyUrl);
Другие вопросы по тегам