HttpClient (Windows.Web.Http), работающий с файлами cookie

Я работаю над приложением для Windows, и у меня возникают проблемы с файлами cookie. Обратите внимание, что я работаю с Windows.Web.Http, а не с пространством имен System HttpClient.

API, с которым я работаю, использует для аутентификации заголовок авторизации. По сути, после POST для входа в систему мне нужен способ вернуть файлы cookie, а затем использовать эти файлы cookie для выполнения последующих вызовов API. Я разместил пример того, что у меня есть в настоящее время, и это удается. Я вижу файлы cookie в объекте результата. Я просто не совсем уверен, куда идти отсюда / как действовать дальше. Спасибо! Любые идеи?

using MyApi.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Web.Http;
using Newtonsoft.Json;
using MyApi.Models.Auth;
using MyApi.Models;

namespace MyApi
{
    public class MyService
    {
        private const string MyBaseUrl = "http://api.my.com:3000";
        private readonly HttpClient _httpClient = new HttpClient();

    public async Task<SignInResponse> AttemptLogin(string username, string password)
    {
        if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
            throw new ArgumentException("Username or password is null or empty");

        var uri = new Uri(string.Format("{0}/{1}", MyBaseUrl, "auth/signin"));

        var authSignIn = new Models.Auth.SignInRequest();
        authSignIn.Email = username;
        authSignIn.Password = password;

        var myObject = JsonConvert.SerializeObject(authSignIn);

        // I see the headers in the result object, but I'm not 
        // sure the best way to a) get them out and b) shove them into
        // all of the next calls
        var result = await _httpClient.PostAsync(uri, 
            new HttpStringContent(myObject.ToString(), 
                Windows.Storage.Streams.UnicodeEncoding.Utf8, 
                "application/json"));

        var content = await result.Content.ReadAsStringAsync();
        var successResponse = new SignInResponse();

        try
        {
            successResponse = JsonConvert.DeserializeObject<SignInResponse>(content);
        }
        catch (Exception)
        {
            var failResponse = JsonConvert.DeserializeObject<ErrorResponse>(content);
            throw new Exception(failResponse.message);
        }

        return successResponse;
    }
}
}

person YnotDraw    schedule 09.07.2015    source источник
comment
Взгляните на CookieContainer в следующем сообщении... stackoverflow.com/questions/12373738/   -  person 3-14159265358979323846264    schedule 10.07.2015
comment
Это фактически использует пространство имен System.Net, а мое использует Windows.Web.Http. Не похоже, что контейнер cookie доступен для пространства имен, с которым я работаю.   -  person YnotDraw    schedule 10.07.2015
comment
Привет, @YnotDraw Вы нашли решение своего вопроса?   -  person alminh    schedule 09.03.2017


Ответы (2)


Вы можете использовать HttpBaseProtocolFilter.CookieManager, например:

var filter = new HttpBaseProtocolFilter();
var cookieManager = filter.CookieManager;

var uri = new Uri("http://api.my.com:3000");
foreach (var cookie in cookieManager.GetCookies(uri))
{
    Debug.WriteLine(cookie.Name);
    Debug.WriteLine(cookie.Value);
}

Обратите внимание: если файлы cookie уже находятся в HttpCookieContainer, они будут автоматически добавлены в следующих запросах к http://api.my.com:3000, и с вашей стороны не требуется никаких действий.

Если вы хотите изменить или удалить их, HttpCookieContainer имеет методы для этого.

person kiewic    schedule 10.07.2015

Взгляните на Flurl. Он представляет собой свободный интерфейс для битов Http, поэтому вы можете сказать что-то вроде этого для аутентификации и повторного использования соединения с файлами cookie:

using (var fc = new FlurlClient().EnableCookies())
{
  var url = new Url( "http://api.com/endpoint" ) ;

  await url
        .AppendPathSegment("login")
        .WithClient(fc)
        .PostUrlEncodedAsync(new { user = "user", pass = "pass" });

  var page = await url
             .AppendPathSegment("home")
             .WithClient(fc)
             .GetStringAsync();

  // Need to inspect the cookies? FlurlClient exposes them as a dictionary.
  var sessionId = fc.Cookies["session_id"].Value;

}
person Nicholas Carey    schedule 10.07.2015