简体   繁体   English

如何“刷新”通过HttpClient返回的cookie

[英]How to “refresh” cookie returned with HttpClient

I work on a Xamarin.Forms project where I call some WebServices that using cookies , as they was intially made for a website. 我在Xamarin.Forms项目中工作,在其中我称一些使用cookie的 WebServices ,因为它们最初是为网站制作的。 There are some webservices that only return cookies, but ohers need to receive cookies for working well. 有些Web服务仅返回cookie,但是为了正常工作,其他人需要接收cookie。

For example, the Login webservice gets a JSON and returns 2 cookies, while the Logout webservice gets an "empty" JSON, the 2 previous cookies and must return an updated value for one of these cookies. 例如, 登录 Web服务获取一个JSON并返回2个cookie,而注销 Web服务获取一个“空” JSON,即先前的2个cookie,并且必须返回其中一个cookie的更新值。

I based on the following link to manage cookies with HttpClient: Struggling trying to get cookie out of response with HttpClient in .net 4.5 我基于以下链接来管理HttpClient的Cookie: 尝试在.net 4.5中使用HttpClient来使Cookie脱离响应

My problem is that I can send a cookie to a webservice, I can receive the returned cookie by a webservice, but I can't receive any "updated" cookie if I've sent it before the call... 我的问题是我可以将cookie发送到Web服务,可以通过Web服务接收返回的cookie,但是如果我在呼叫之前发送了它,那么我将不会收到任何“更新的” cookie。

The code of the call to the Login webservice looks like this: 调用登录 Web服务的代码如下所示:

public async Task Login()
{
    Uri uri = new Uri("http://www.website.com/Login");

    CookieContainer cookies = new CookieContainer();
    HttpClientHandler handler = new HttpClientHandler();
    handler.CookieContainer = cookies;

    var httpClient = new HttpClient(handler);

    var jsonParam = "{\"data\":{\"device\":\"xxx\",\"login\":\"my@email.com\",\"password\":\"password\"}}";

    HttpContent httpContent = new StringContent(jsonParam);
    httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

    httpClient.DefaultRequestHeaders.Add("X-HTTP-Method-Override", "PUT");
    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    try
    {
        HttpResponseMessage httpResponse = httpClient.PostAsync(uri), httpContent).Result;
        //Treatment of the recovered cookies
        IEnumerable<Cookie> responseCookies = cookies.GetCookies(uri).Cast<Cookie>();
        foreach (Cookie cookie in responseCookies)
        {
            Debug.WriteLine(cookie.Name + " : " + cookie.Value);
            wsCookies.Add(new KeyValuePair<string, string>(cookie.Name, cookie.Value));
        }

        if (httpResponse.IsSuccessStatusCode)
        {
            var responseText = await httpResponse.Content.ReadAsStringAsync();
        }
    }
    catch (Exception e)
    {

    }
}

=> it works well: I get the expected cookies: SESSIONID=xxx and USERID=xxx =>效果很好:我得到了预期的Cookie: SESSIONID = xxxUSERID = xxx

The code of my Logout method looks like this: 我的注销方法的代码如下所示:

public async Task Logout(String test)
{
    Uri uri = new Uri("http://www.website.com/Logout");

    CookieContainer cookies = new CookieContainer();
    HttpClientHandler handler = new HttpClientHandler();
    handler.CookieContainer = cookies;

    var httpClient = new HttpClient(handler);

    var jsonParam = "{\"data\":{}}";

    HttpContent httpContent = new StringContent(jsonParam);
    httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

    httpClient.DefaultRequestHeaders.Add("X-HTTP-Method-Override", "GET");
    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    //Retrieving cookies to send
    foreach (KeyValuePair<string, string> kvpCookie in wsCookies)
    {
        cookies.Add(uri, new Cookie(kvpCookie.Key, kvpCookie.Value));
    }

    try
    {
        HttpResponseMessage httpResponse = httpClient.PostAsync(uri, httpContent).Result;
        //Treatment of the recovered cookies
        IEnumerable<Cookie> responseCookies = cookies.GetCookies(uri).Cast<Cookie>();
        foreach (Cookie cookie in responseCookies)
        {
            Debug.WriteLine(cookie.Name + " : " + cookie.Value);
            wsCookies.Add(new KeyValuePair<string, string>(cookie.Name, cookie.Value));
        }

        if (httpResponse.IsSuccessStatusCode)
        {
            var responseText = await httpResponse.Content.ReadAsStringAsync();
        }
    }
    catch (Exception e)
    {

    }
}

=> this method works but I don't get the expected cookies. =>此方法有效,但是我没有得到预期的cookie。 I send the cookies (names and values) that I've received earlier ( SESSIONID=xxx and USERID=xxx ), but I don't get a new value for the cookies, whereas I wait USERID=deleted as I can see when I sniff it in Fiddler: I only find the 2 cookies I've sent in " responseCookies "... 我发送了早些时候收到的Cookie(名称和值)( SESSIONID = xxxUSERID = xxx ),但是没有得到新的Cookie值,但是我等待USERID = deleted,因为我看到了在Fiddler中嗅探它:我只在“ responseCookies ”中找到了我发送的2个cookie ...

=> Do you have an explanation? =>您有解释吗? Is there something that I'm doing wrong? 我做错什么了吗? Is there another way to manage webservices and cookies? 还有另一种管理Web服务和Cookie的方法吗?

Not sure if that is the issue, but why create the cookie container every time? 不知道这是否是问题,但是为什么每次都要创建cookie容器? You can pass the cookies along every time. 您可以每次传递cookie。

So initialize once, and then assign the existing cookie container to the requests in Login and Logout . 因此,初始化一次,然后将现有的cookie容器分配给LoginLogout的请求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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