18

Hi I am developing one Iphone application In which I want to set cookies after server response and use that for another request. My network request looks like.

NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
    NSHTTPURLResponse *httpResp = (NSHTTPURLResponse*) response;
    NSLog(@"sttaus code %i", httpResp.statusCode);
    if (error) {
        [self.delegate signinWithError:error];
    }
    else {
        [self.delegate signinWithJson:data];
    }
}] resume];

But I don't know how to set cookies. I know I have to use NSHTTPCookieStorage but I don't know how to set. And I also want to use that cookies for another request. Is there any one who knows about this? Need help. Thank you.

See I tried in this way

NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{      
    if(error) {
        [self.delegate signinWithError:error];
    }
    else {
        NSHTTPURLResponse *httpResp = (NSHTTPURLResponse*) response;

        [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
        NSHTTPCookie *cookie;

        NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];

        NSDictionary* headers = [(NSHTTPURLResponse *)response allHeaderFields];

        for(NSString *key in [headers allKeys]) {
            NSLog(@"%@ ..PPPP ... %@",key ,[headers objectForKey:key]);
            [cookieProperties setObject:[headers objectForKey:key] forKey:key];
        }

        [cookieProperties setObject:[[NSDate date] dateByAddingTimeInterval:2629743] forKey:NSHTTPCookieExpires];

        cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];

        [self.delegate signinWithJson:data];
    }
}] resume];

I am interested in only one header field Set-Cookie SSID=kgu62c0fops35n6qbf12anqlo7; path=/

David
  • 3,285
  • 1
  • 37
  • 54
nilkash
  • 7,408
  • 32
  • 99
  • 176

2 Answers2

17

You can probably get away with just using the sharedHTTPCookieStorage for NSHTTPCookieStorage, and then use setCookies:forURL:mainDocumentURL: or the single setCookie: - the latter might be better for your needs.

If this doesn't work you might need to setup the NSURLSessionConfiguration and set the NSHTTPCookieStorage

The docs don't state it, but the defaultSessionConfiguration might use the shared store anyway.

NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
    NSHTTPURLResponse *httpResp = (NSHTTPURLResponse*) response;

    NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:[response allHeaderFields] forURL:[response URL]];
    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:cookies forURL:[response URL] mainDocumentURL:nil];

    NSLog(@"sttaus code %i", httpResp.statusCode);
    if (error) {
        [self.delegate signinWithError:error];
    }
    else {
        [self.delegate signinWithJson:data];
    }
}] resume];
David
  • 3,285
  • 1
  • 37
  • 54
Rich
  • 8,108
  • 5
  • 46
  • 59
  • I have header fields after login request. So I have two way to do this one add my session id (or require fields) into user's data or save it as cookies. I decided cookies to use. But I don't know how to create and how to pass cookies with NSURLSESSION . – nilkash Apr 22 '14 at 12:43
  • Can you post the header fields please - feel free to remove important data – Rich Apr 22 '14 at 12:44
  • Ad you have the cookie in the response - I thought you wanted to set it on the request – Rich Apr 22 '14 at 12:52
  • :). See this is full scenario. User will login to my app. after login I have to maintain session for that user. So what I am doing once User logged in I am saving session id for some time. So if user do some activities in my app I need that session id. Otherwise server gives 401 error. So after login for any request I am passing that session id for authentication on sever side. Is this the correct way or there is better way. Happy to accept better one :) – nilkash Apr 22 '14 at 12:56
  • There we go, try that - if that doesn't work you might need to use a custom session config, let me know – Rich Apr 22 '14 at 13:00
  • This will create cookie for me but how can I add this one into other request header. Is there any way by which my request can use cookies by default. I think there is one configuration. I am not sure. Is there any? In android cookie store is there. Is there any such thing for IOS. – nilkash Apr 22 '14 at 13:10
  • Do the other requests have the same domain/path as the cookie is set on? – Rich Apr 22 '14 at 13:12
  • I am not interested in other part of cookies I am interested in session filed. `Set-Cookies` and its value – nilkash Apr 22 '14 at 13:13
  • The other parts of the cookie are important - they define where the cookie can be used. – Rich Apr 22 '14 at 13:14
  • ok. But in android I use only session id and that works :). I am happy to send send all cookie part but don't know how to send with `NSURLSESSION`. And all request are in same domain. – nilkash Apr 22 '14 at 13:17
  • I've already posted how to send cookies with `NSURLSession`. Even in android you still need to [set cookies against a URL](http://developer.android.com/reference/android/webkit/CookieManager.html#setCookie%28java.lang.String,%20java.lang.String%29) (and `java.net.CookieStore` [is the same](http://developer.android.com/reference/java/net/CookieStore.html#add%28java.net.URI,%20java.net.HttpCookie%29)). Post your android code as well... – Rich Apr 22 '14 at 13:21
  • I don't have android code now will post it soon. And will try this one let you know whether works or not :) – nilkash Apr 22 '14 at 13:24
  • 3
    Any requests that use the `sharedSession` will use the shared cookie store, so they will pick up any cookies that have a matching domain and path. – Rich Apr 22 '14 at 13:26
  • instead of saving all header field can I store only few values and use them ? – nilkash Apr 22 '14 at 13:31
  • `cookiesWithResponseHeaderFields:forURL:` extracts only the `Set-Cookie` headers. You can iterate through this list and pull out the ones you want to use, but you *still* need to set them against a URL. Unless you don't want to set any of the other cookies, you might as well just set them all – Rich Apr 22 '14 at 13:34
  • No, sorry. And I've done it multiple ways - using cookies, Oauth, session tokens, basic auth. This method should work for what you wan to do. – Rich Apr 22 '14 at 13:45
-10

I researched a lot but found one in a website of another language. The solution is to add an empty event handler for session start and end:

protected void Session_Start(object sender, EventArgs e)
{
}
protected void Session_End(object sender, EventArgs e)
{
}
JLT
  • 3,052
  • 9
  • 39
  • 86
Carson
  • 35
  • 8
  • 4
    I'm not sure if you answered the wrong question here by mistake or what, but this answer is absolutely unrelated to the question. – shortstuffsushi Dec 07 '16 at 05:03