14

I'm trying to create a login in my iPhone App.

NSURL *urlNew = [NSURL URLWithString:urlstring];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:urlNew];
NSString *msgLength = [NSString stringWithFormat:@"%d", [parameterString length]];
[theRequest addValue: msgLength forHTTPHeaderField:@"Content-Length"];
[theRequest setHTTPMethod:@"POST"];
[theRequest setValue:length forHTTPHeaderField:@"Content-Length"];
[theRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[theRequest setHTTPBody: httpbody];
         
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES];
         
[connection start];

That's the way how I post my data to the Server, it works - I get a response. The problem is, that the response is the code of the Login-side, not the code of the "saved" area. I think I have to create cookies, so that the website knows, that I am logged in.

I searched on the Internet but I didn't find anything useful. So how do I create a cookie, when I am logging in? Do I have to post this cookie every time, when I am going to another link in the "saved" area?

Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220
Schmarsi
  • 141
  • 1
  • 1
  • 3
  • You should change your question to "How to get a Cookie with a NSURLRequest?" since you said you want to get the existing cookie not creating a new one. – Maziyar May 27 '14 at 06:40

4 Answers4

33

Try this

[theRequest setValue:@"myCookie" forHTTPHeaderField:@"Cookie"];

Edit:

OP wants to know how to create a cookie. So here is some code

NSDictionary *cookieProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                        @"domain.com", NSHTTPCookieDomain,
                        @"\\", NSHTTPCookiePath,  
                        @"myCookie", NSHTTPCookieName,
                        @"1234", NSHTTPCookieValue,
                        nil];
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
NSArray* cookieArray = [NSArray arrayWithObject:cookie];
NSDictionary * headers = [NSHTTPCookie requestHeaderFieldsWithCookies:cookieArray];
[request setAllHTTPHeaderFields:headers];
Frank Schmitt
  • 25,648
  • 10
  • 58
  • 70
mbh
  • 3,302
  • 2
  • 22
  • 24
  • Thanks, but I don't unterstand it. For "myCookie" I have to fill in something? – Schmarsi Feb 12 '12 at 17:53
  • The first time I login, I have to create a cookie I thought. To load another link I have to send this created cookie with the request, right? How do I handle this? – Schmarsi Feb 12 '12 at 17:55
  • 1
    Thanks, but I don't want to create a cookie by myself. I want to get the cookie while I am loggin me into the website from the server. So I need to "catch" the cookie, right? How do I solve this? I googled much time, but didn't find anything useful... :( – Schmarsi Feb 13 '12 at 07:11
  • @Schmarsi I am facing to the same issue, have you found out the answer? could you please share that with me? thanks! :) – trillions Feb 24 '13 at 09:43
  • 1
    You should change the first example to `[theRequest setValue:@"myCookie=1234" forHTTPHeaderField:@"Cookie"];` which is equivlant to the second one. – ideawu Dec 18 '14 at 07:14
  • +1 for NSHTTPCookie.requestHeaderFieldsWithCookies - I was trying to find a method to add existing cookies to a request, and kept looking in NSHTTPRequest. Never would've thought to look from the other side. – MandisaW Mar 24 '16 at 20:26
4

not sure it's still relevant, but in case someone find that useful, here's how you get the cookies after making a request. You should implement the selector connectionDidFinishLoading: in the object that was specified as a delegate to NSURLConnection (self in your case):

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES];

in this connectionDidFinishLoading: selector you can access the cookies like that:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSHTTPCookieStorage * storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    NSArray * cookies = [storage cookiesForURL:connection.currentRequest.URL];
    for (NSHTTPCookie * cookie in cookies)
    {
        NSLog(@"%@=%@", cookie.name, cookie.value);
        // Here you can store the value you are interested in for example
    }
}

then later, this stored value can be used in requests like this:

[request setValue:[NSString stringWithFormat:@"%@=%@", cookieName, cookieValue] forHTTPHeaderField:@"Cookie"];

or more advanced setAllHTTPHeaderFields:, but remember to use the correct value in NSHTTPCookiePath field, see details here

also NSHTTPCookieStorage has selector -setCookies:forURL:mainDocumentURL: that can also be used to set cookies.

Community
  • 1
  • 1
3

I had the same problem with a WKWebView showing the cookie on a PHP page on initial load but the cookie was cleared when page was reloaded/refreshed. Here's what I did to make it work.

My WKWebView with the cookie setting:

WKWebViewConfiguration *webViewConfig = [[WKWebViewConfiguration alloc] init]; // empty for now
_awesomeWebView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:webViewConfig];
_awesomeWebView.UIDelegate = self;
[self.view addSubview:_awesomeWebView];

NSString *url = @"https://phpwebsitewithcookiehandling.com";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];

// set all the cookies from my NSHTTPCookieStorage in the WKWebView too
[request setHTTPShouldHandleCookies:YES];
[request setAllHTTPHeaderFields:[NSHTTPCookie requestHeaderFieldsWithCookies:[NSHTTPCookieStorage sharedHTTPCookieStorage].cookies]];

// set the cookie on the initial load
NSString *cookie = @"status=awesome";
[request setValue:cookie forHTTPHeaderField:@"Cookie"];
NSLog(@"cookie set in WKwebView header: %@", cookie);

[_awesomeWebView loadRequest:request];

On my phpwebsitewithcookiehandling.com I used the following to verify it worked:

<?php
    echo "<li>status is: " . $_COOKIE['status'];

    // Here comes the magic which set the servers SET-COOKIE header (apparently) so it works on consecutive page loads
    setcookie('status', $_COOKIE['status'], time() + (86400 * 30), '/');

    echo '<li><a href="">Blank reload</a>';
    echo '<li><a href="#" onclick="location.reload(true);">Javascript reload</a>';

    exit;
?>

It worked for me after much trial and error. Good luck. :)

holm50
  • 821
  • 8
  • 7
1

There is source code to extract cookie string from NSHTTPURLResponse:

static NSString *CookieFromResponse(NSHTTPURLResponse *response) {
    NSArray<NSHTTPCookie *> *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:response.allHeaderFields forURL:response.URL];

    NSMutableString *cookieStr = [NSMutableString string];
    for (NSHTTPCookie *cookie in cookies) {
        if (cookieStr.length) {
            [cookieStr appendString:@"; "];
        }
        [cookieStr appendFormat:@"%@=%@", cookie.name, cookie.value];
    }
    return cookieStr.length ? cookieStr : nil;
}

And to set cookie string to NSMutableURLRequest:

NSString *cookieStr = CookieFromResponse(response);
[request addValue:cookieStr forHTTPHeaderField:@"Cookie"];
k06a
  • 17,755
  • 10
  • 70
  • 110