1

I am a complete n00b with Obj-C and I'm stuck on this simple thing for hours. I am using a UIWebView to load a page which asks for username and password. When I login successfully, my server sends me a cookie with an Id that I want to post to a PHP script in order to store it in db.

When login is successful I get redirected to a new url.

I can read the cookie value and send a POST request to the appropriate script (from my WebView delegate) but doing so, invalidates my login and my page is asking me again for password.

Is this completely wrong approach? Any help on that?

[NSURLConnection connectionWithRequest:request delegate:self];

This is the line of code I run before my session gets invalidated. If I call this from inside the ViewController it works fine, but I need it to run only when I am on a specific url (after login) that's why I have put it in delegate.

Complete (messy) code follows.

 NSURL *url = [NSURL URLWithString:@"https://www.example.com/api/register”];
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];


    NSHTTPCookie *cookie;
    NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    NSString *userid;

    for (cookie in [cookieJar cookies]) {

        if ([cookie.name  isEqual: @“cookie_user_id"]) {
            userid = cookie.value;
            NSLog(@"%@",cookie);

        }

    }


    NSString *getToken = [[NSUserDefaults standardUserDefaults] stringForKey:@"DEVICE_TOKEN"];
    NSString *user_id = [NSString stringWithFormat:@"user_id=%@", userid];
    NSString *dtk = [NSString stringWithFormat:@"&token=%@",getToken];
    NSString *params = [NSString stringWithFormat: @"%@ %@", user_id, dtk];


    NSData *requestData = [params dataUsingEncoding:NSUTF8StringEncoding];

    [request setHTTPMethod:@"POST"];
    [request setValue:@"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" forHTTPHeaderField:@"Accept"];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    [request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)[requestData length]] forHTTPHeaderField:@"Content-Length"];
    [request setHTTPBody: requestData];


    [NSURLConnection connectionWithRequest:request delegate:self];
Peter Foti
  • 5,526
  • 6
  • 34
  • 47
Shardon
  • 585
  • 5
  • 17
  • Can you add the code where you setup the `request` which you are sending there? – Leijonien Nov 17 '13 at 21:38
  • Just did, thanks for your effort. – Shardon Nov 17 '13 at 21:53
  • Don't know if it's gonna help, but can you try adding another http header for key `User-Agent`, something like this: `[request addValue:@"Mozilla/5.0 (iPad; CPU OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Mobile/11A465" forHTTPHeaderField:@"User-Agent"];`. This is the header as sent by UIWebView requests and servers might act different based on that header, since you're using that header while authenticating, but you don't use the header in follow up requests. Just a guess.. – Leijonien Nov 17 '13 at 22:05
  • nope, no change with that. I have noticed that there is a PHPSESSID cookie appearing sometimes if I NSLog the cookies. For some reason NSURLConnection doesn't keep my session data I think. – Shardon Nov 17 '13 at 22:10
  • Do you really need to handle the cookies yourself? (You Shouldn't need to because UIWebView and NSURLConnection will by default handle them.. Another question: Can't you just authenticate using NSURLConnection? (I'm basically using that all the time in my apps, also for HTML form based authentication, and never have to handle cookies myself.) – Leijonien Nov 17 '13 at 22:18
  • I only want to get the value of my cookie_user_id to use it in the post. Other than that, I would expect UIWebView and NSURLConnection to handle them but I keep losing authentication. Also, I need to go through the login form. How would I do that with NSURLConnection? – Shardon Nov 17 '13 at 22:46
  • You can capture the postdata from the UIWebViewRequest, convert it to NSString, replace username and password by `%@` (to create a string format). Before sending the login request, you just use this string format to fill in the username and password, convert it to NSData and add it to the post request, basically just like the request you are using now. – Leijonien Nov 17 '13 at 22:59
  • Cool, but I want my app's user to be presented with the login form – Shardon Nov 17 '13 at 23:02
  • Then you can just implement `webView:shouldStartLoadWithRequest:navigationType:` and return NO, so the webview won't actually send it (but keep a reference to the request in the parameter!), and then rebuild your own request based on that request or send that request by yourself using NSURLConnection. – Leijonien Nov 17 '13 at 23:11

1 Answers1

0

Ok, it seems that everything was just right from the beginning. The website of my server is running on Code Igniter which has a setting for destroying sessions if the user agent has changed. This, was causing a logout with every post to my api's endpoint.

Lost 3 days looking for that, I wish I have tested a post to a testing server :S

This post explains a lot: http://mirkules.com/blog/asihttprequest-vs-nsurlrequest/

***Just noticed that Leijonien's answer (comment) was in the right direction from the beginning...

Shardon
  • 585
  • 5
  • 17