简体   繁体   中英

HttpClient (Windows.Web.Http) working with cookies

I am working on a Windows app and am having some issues with cookies. Please note that I am working with Windows.Web.Http, not the System namespace HttpClient.

The API I'm working with uses an auth-header for authentication. Basically after a POST to login, I need a way to get the cookies returned and then use those cookies to perform the subsequent API calls. I posted an example of what I currently have, which succeeds. I can see the cookies in the result object. I'm just not entirely sure where to go from here / how to proceed. Thanks! Any ideas?

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;
    }
}
}

You can use HttpBaseProtocolFilter.CookieManager , eg:

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);
}

Notice, if the cookies are already in the HttpCookieContainer , the cookies will be automatically added in the next requests to http://api.my.com:3000 , and no action is required from your side.

If you want to modify them or delete them, the HttpCookieContainer has methods to do that.

Take a look at Flurl . It presents a fluent interface over the Http bits, so you can say something like this to authenticate and reuse the connection with the cookies:

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;

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM