I have an iOS app that needs to login to an existing site that uses Django and requires a CSRF token to login. I cannot change that.
My current attempt was to send a GET to the server which would return a CSRF, and then grab that cookie as a string and append it to the POST request.
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:@"http://example.com"]];
[req setHTTPShouldHandleCookies:YES];
[NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
self.csrf_cookie = [[(NSHTTPURLResponse *)response allHeaderFields] valueForKey:@"Set-Cookie"];
[self postLoginCredentialsEmail:@"user@example.com" password:@"password"];
}];
- (void)postLoginCredentialsEmail:(NSString *)email password:(NSString *)password {
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:@"http://example.com/login"]];
[req addValue:(self.csrf_cookie != nil ? self.csrf_cookie : @"poo") forHTTPHeaderField:@"X-CSRFToken"];
[req setHTTPMethod:@"POST"];
NSString *postData = [NSString stringWithFormat:@"password=%@&;email=%@", password, email];
[req setValue:@"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:@"Content-type"];
[req setHTTPBody:[postData dataUsingEncoding:NSUTF8StringEncoding]];
[NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSLog(@"response from login: %@", response);
}];
}
I am getting the cookie, but I still get an "incorrect or missing CSRF token" error.
I've seen other posts here, and that's where most of this code comes from but its still failing.
I've compared what is received by the server on my request vs what is received on a good request from the website, and the only difference seems to be that the good request has an HTTP header field HTTP_X_CSRFTOKEN
with just the CSRF token whereas my request has the format 'HTTP_X_CSRFTOKEN': 'csrftoken=tokenkey; expires=expirydate; Max-Age=age; Path=/, mws-track-id=somestuff; httponly; Path=/',